Browse Source

2023-03-13 first commit demo practice

xingyankai 2 years ago
commit
b1f9963e35
100 changed files with 6627 additions and 0 deletions
  1. 49 0
      .gitignore
  2. 30 0
      .metadata
  3. 35 0
      README.md
  4. 1 0
      analysis_options.yaml
  5. 13 0
      android/.gitignore
  6. 71 0
      android/app/build.gradle
  7. 8 0
      android/app/src/debug/AndroidManifest.xml
  8. 34 0
      android/app/src/main/AndroidManifest.xml
  9. 6 0
      android/app/src/main/kotlin/com/example/material_3_demo/MainActivity.kt
  10. 12 0
      android/app/src/main/res/drawable-v21/launch_background.xml
  11. 12 0
      android/app/src/main/res/drawable/launch_background.xml
  12. BIN
      android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  13. BIN
      android/app/src/main/res/mipmap-mdpi/ic_launcher.png
  14. BIN
      android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  15. BIN
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  16. BIN
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  17. 18 0
      android/app/src/main/res/values-night/styles.xml
  18. 18 0
      android/app/src/main/res/values/styles.xml
  19. 8 0
      android/app/src/profile/AndroidManifest.xml
  20. 31 0
      android/build.gradle
  21. 3 0
      android/gradle.properties
  22. 6 0
      android/gradle/wrapper/gradle-wrapper.properties
  23. 11 0
      android/settings.gradle
  24. 34 0
      ios/.gitignore
  25. 26 0
      ios/Flutter/AppFrameworkInfo.plist
  26. 2 0
      ios/Flutter/Debug.xcconfig
  27. 2 0
      ios/Flutter/Release.xcconfig
  28. 44 0
      ios/Podfile
  29. 481 0
      ios/Runner.xcodeproj/project.pbxproj
  30. 7 0
      ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  31. 8 0
      ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  32. 8 0
      ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
  33. 87 0
      ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
  34. 7 0
      ios/Runner.xcworkspace/contents.xcworkspacedata
  35. 8 0
      ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  36. 8 0
      ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
  37. 13 0
      ios/Runner/AppDelegate.swift
  38. 122 0
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
  39. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  40. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
  41. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
  42. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
  43. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
  44. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
  45. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
  46. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
  47. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
  48. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
  49. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
  50. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
  51. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
  52. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
  53. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
  54. 23 0
      ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
  55. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
  56. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
  57. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
  58. 5 0
      ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
  59. 37 0
      ios/Runner/Base.lproj/LaunchScreen.storyboard
  60. 26 0
      ios/Runner/Base.lproj/Main.storyboard
  61. 49 0
      ios/Runner/Info.plist
  62. 1 0
      ios/Runner/Runner-Bridging-Header.h
  63. 339 0
      lib/color_palettes_screen.dart
  64. 2308 0
      lib/component_screen.dart
  65. 40 0
      lib/constants.dart
  66. 184 0
      lib/elevation_screen.dart
  67. 665 0
      lib/home.dart
  68. 35 0
      lib/main.dart
  69. 85 0
      lib/main_bak.dart
  70. 33 0
      lib/myself/my_home.dart
  71. 63 0
      lib/typography_screen.dart
  72. 7 0
      macos/.gitignore
  73. 2 0
      macos/Flutter/Flutter-Debug.xcconfig
  74. 2 0
      macos/Flutter/Flutter-Release.xcconfig
  75. 12 0
      macos/Flutter/GeneratedPluginRegistrant.swift
  76. 43 0
      macos/Podfile
  77. 791 0
      macos/Runner.xcodeproj/project.pbxproj
  78. 8 0
      macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  79. 98 0
      macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
  80. 10 0
      macos/Runner.xcworkspace/contents.xcworkspacedata
  81. 8 0
      macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  82. 9 0
      macos/Runner/AppDelegate.swift
  83. 68 0
      macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
  84. BIN
      macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
  85. BIN
      macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
  86. BIN
      macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
  87. BIN
      macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
  88. BIN
      macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
  89. BIN
      macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
  90. BIN
      macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
  91. 343 0
      macos/Runner/Base.lproj/MainMenu.xib
  92. 14 0
      macos/Runner/Configs/AppInfo.xcconfig
  93. 2 0
      macos/Runner/Configs/Debug.xcconfig
  94. 2 0
      macos/Runner/Configs/Release.xcconfig
  95. 13 0
      macos/Runner/Configs/Warnings.xcconfig
  96. 12 0
      macos/Runner/DebugProfile.entitlements
  97. 32 0
      macos/Runner/Info.plist
  98. 15 0
      macos/Runner/MainFlutterWindow.swift
  99. 8 0
      macos/Runner/Release.entitlements
  100. 12 0
      macos/RunnerTests/RunnerTests.swift

+ 49 - 0
.gitignore

@@ -0,0 +1,49 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+migrate_working_dir/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+**/ios/Flutter/.last_build_id
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+
+# Web related
+lib/generated_plugin_registrant.dart
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
+
+# Android Studio will place build artifacts here
+/android/app/debug
+/android/app/profile
+/android/app/release
+*.lock
+*test

+ 30 - 0
.metadata

@@ -0,0 +1,30 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled.
+
+version:
+  revision: 610450523b20e59f42a908d6bc711a739e7d85e8
+  channel: master
+
+project_type: app
+
+# Tracks metadata for the flutter migrate command
+migration:
+  platforms:
+    - platform: root
+      create_revision: 610450523b20e59f42a908d6bc711a739e7d85e8
+      base_revision: 610450523b20e59f42a908d6bc711a739e7d85e8
+    - platform: macos
+      create_revision: 610450523b20e59f42a908d6bc711a739e7d85e8
+      base_revision: 610450523b20e59f42a908d6bc711a739e7d85e8
+
+  # User provided section
+
+  # List of Local paths (relative to this file) that should be
+  # ignored by the migrate tool.
+  #
+  # Files that are not part of the templates will be ignored by default.
+  unmanaged_files:
+    - 'lib/main.dart'
+    - 'ios/Runner.xcodeproj/project.pbxproj'

+ 35 - 0
README.md

@@ -0,0 +1,35 @@
+# Material 3 Demo
+
+This sample Flutter app showcases Material 3 features in the Flutter Material library. These features include updated components, typography, color system and elevation support. The app supports light and dark themes, different color palettes, as well as the ability to switch between Material 2 and Material 3. For more information about Material 3, the guidance is now live at https://m3.material.io/.
+
+This app also includes new M3 components such as IconButtons, Chips, TextFields, Switches, Checkboxes, Radio buttons and ProgressIndicators. 
+
+# Preview
+
+<img width="400" alt="Screen Shot 2022-08-12 at 12 00 28 PM" src="https://user-images.githubusercontent.com/36861262/184426137-47b550e1-5c6e-4bb7-b647-b1741f96d42b.png"><img width="400" alt="Screen Shot 2022-08-12 at 12 00 38 PM" src="https://user-images.githubusercontent.com/36861262/184426154-063a39e8-24bd-40be-90cd-984bf81c0fdf.png">
+
+
+# Features
+## Icon Buttons on the Top App Bar
+<img src="https://user-images.githubusercontent.com/36861262/166506048-125caeb3-5d5c-4489-9029-1cb74202dd37.png" width="25"/>  Users can switch between a light or dark theme with this button.
+
+<img src="https://user-images.githubusercontent.com/36861262/166508002-90fce980-d228-4312-a95f-a1919bb79ccc.png" width="25" />  Users can switch between Material 2 and Material 3 for the displayed components with this button.
+
+<img src="https://user-images.githubusercontent.com/36861262/166511137-85dea8df-0017-4649-b913-14d4b7a17c2f.png" width="25" /> This button will bring up a pop-up menu that allows the user to change the base color used for the light and dark themes. This uses a new color seed feature to generate entire color schemes from a single color.
+
+## Component Screen
+The default screen displays all the updated components in Material 3: AppBar, common Buttons, Floating Action Button(FAB), Chips, Card, Checkbox, Dialog, NavigationBar, NavigationRail, ProgressIndicators, Radio buttons, TextFields and Switch.
+
+### Adaptive Layout
+Based on the fact that NavigationRail is not recommended on a small screen, the app changes its layout based on the screen width. If it's played on iOS or Android devices which have a narrow screen, a Navigation Bar will show at the bottom and will be used to navigate. But if it's played as a desktop or a web app, a Navigation Rail will show on the left side and at the same time, a Navigation Bar will show as an example but will not have any functionality.
+
+Users can see both layouts on one device by running a desktop app and adjusting the screen width.
+
+## Color Screen
+With Material 3, we have added support for generating a full color scheme from a single seed color. The Color Screen shows users all of the colors in light and dark color palettes that are generated from the currently selected color.
+
+## Typography Screen
+The Typography Screen displays the text styles used in for the default TextTheme.
+
+## Elevation Screen
+The Elevation screen shows different ways of elevation with a new supported feature "surfaceTintColor" in the Material library.

+ 1 - 0
analysis_options.yaml

@@ -0,0 +1 @@
+include: package:analysis_defaults/flutter.yaml

+ 13 - 0
android/.gitignore

@@ -0,0 +1,13 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
+
+# Remember to never publicly share your keystore.
+# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
+key.properties
+**/*.keystore
+**/*.jks

+ 71 - 0
android/app/build.gradle

@@ -0,0 +1,71 @@
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+    localPropertiesFile.withReader('UTF-8') { reader ->
+        localProperties.load(reader)
+    }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+    throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
+if (flutterVersionCode == null) {
+    flutterVersionCode = '1'
+}
+
+def flutterVersionName = localProperties.getProperty('flutter.versionName')
+if (flutterVersionName == null) {
+    flutterVersionName = '1.0'
+}
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+    compileSdkVersion flutter.compileSdkVersion
+    ndkVersion flutter.ndkVersion
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
+
+    kotlinOptions {
+        jvmTarget = '1.8'
+    }
+
+    sourceSets {
+        main.java.srcDirs += 'src/main/kotlin'
+    }
+
+    defaultConfig {
+        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
+        applicationId "com.example.material_3_demo"
+        // You can update the following values to match your application needs.
+        // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
+        minSdkVersion flutter.minSdkVersion
+        targetSdkVersion flutter.targetSdkVersion
+        versionCode flutterVersionCode.toInteger()
+        versionName flutterVersionName
+    }
+
+    buildTypes {
+        release {
+            // TODO: Add your own signing config for the release build.
+            // Signing with the debug keys for now, so `flutter run --release` works.
+            signingConfig signingConfigs.debug
+        }
+    }
+}
+
+flutter {
+    source '../..'
+}
+
+dependencies {
+    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}

+ 8 - 0
android/app/src/debug/AndroidManifest.xml

@@ -0,0 +1,8 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.material_3_demo">
+    <!-- The INTERNET permission is required for development. Specifically,
+         the Flutter tool needs it to communicate with the running application
+         to allow setting breakpoints, to provide hot reload, etc.
+    -->
+    <uses-permission android:name="android.permission.INTERNET"/>
+</manifest>

+ 34 - 0
android/app/src/main/AndroidManifest.xml

@@ -0,0 +1,34 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.material_3_demo">
+   <application
+        android:label="material_3_demo"
+        android:name="${applicationName}"
+        android:icon="@mipmap/ic_launcher">
+        <activity
+            android:name=".MainActivity"
+            android:exported="true"
+            android:launchMode="singleTop"
+            android:theme="@style/LaunchTheme"
+            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
+            android:hardwareAccelerated="true"
+            android:windowSoftInputMode="adjustResize">
+            <!-- Specifies an Android theme to apply to this Activity as soon as
+                 the Android process has started. This theme is visible to the user
+                 while the Flutter UI initializes. After that, this theme continues
+                 to determine the Window background behind the Flutter UI. -->
+            <meta-data
+              android:name="io.flutter.embedding.android.NormalTheme"
+              android:resource="@style/NormalTheme"
+              />
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+        <!-- Don't delete the meta-data below.
+             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
+        <meta-data
+            android:name="flutterEmbedding"
+            android:value="2" />
+    </application>
+</manifest>

+ 6 - 0
android/app/src/main/kotlin/com/example/material_3_demo/MainActivity.kt

@@ -0,0 +1,6 @@
+package com.example.material_3_demo
+
+import io.flutter.embedding.android.FlutterActivity
+
+class MainActivity: FlutterActivity() {
+}

+ 12 - 0
android/app/src/main/res/drawable-v21/launch_background.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Modify this file to customize your launch splash screen -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="?android:colorBackground" />
+
+    <!-- You can insert your own image assets here -->
+    <!-- <item>
+        <bitmap
+            android:gravity="center"
+            android:src="@mipmap/launch_image" />
+    </item> -->
+</layer-list>

+ 12 - 0
android/app/src/main/res/drawable/launch_background.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Modify this file to customize your launch splash screen -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@android:color/white" />
+
+    <!-- You can insert your own image assets here -->
+    <!-- <item>
+        <bitmap
+            android:gravity="center"
+            android:src="@mipmap/launch_image" />
+    </item> -->
+</layer-list>

BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher.png


BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher.png


BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png


BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png


BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png


+ 18 - 0
android/app/src/main/res/values-night/styles.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
+    <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
+        <!-- Show a splash screen on the activity. Automatically removed when
+             the Flutter engine draws its first frame -->
+        <item name="android:windowBackground">@drawable/launch_background</item>
+    </style>
+    <!-- Theme applied to the Android Window as soon as the process has started.
+         This theme determines the color of the Android Window while your
+         Flutter UI initializes, as well as behind your Flutter UI while its
+         running.
+
+         This Theme is only used starting with V2 of Flutter's Android embedding. -->
+    <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
+        <item name="android:windowBackground">?android:colorBackground</item>
+    </style>
+</resources>

+ 18 - 0
android/app/src/main/res/values/styles.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
+    <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
+        <!-- Show a splash screen on the activity. Automatically removed when
+             the Flutter engine draws its first frame -->
+        <item name="android:windowBackground">@drawable/launch_background</item>
+    </style>
+    <!-- Theme applied to the Android Window as soon as the process has started.
+         This theme determines the color of the Android Window while your
+         Flutter UI initializes, as well as behind your Flutter UI while its
+         running.
+
+         This Theme is only used starting with V2 of Flutter's Android embedding. -->
+    <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
+        <item name="android:windowBackground">?android:colorBackground</item>
+    </style>
+</resources>

+ 8 - 0
android/app/src/profile/AndroidManifest.xml

@@ -0,0 +1,8 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.material_3_demo">
+    <!-- The INTERNET permission is required for development. Specifically,
+         the Flutter tool needs it to communicate with the running application
+         to allow setting breakpoints, to provide hot reload, etc.
+    -->
+    <uses-permission android:name="android.permission.INTERNET"/>
+</manifest>

+ 31 - 0
android/build.gradle

@@ -0,0 +1,31 @@
+buildscript {
+    ext.kotlin_version = '1.6.10'
+    repositories {
+        google()
+        mavenCentral()
+    }
+
+    dependencies {
+        classpath 'com.android.tools.build:gradle:4.1.0'
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+    }
+}
+
+allprojects {
+    repositories {
+        google()
+        mavenCentral()
+    }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+    project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+    project.evaluationDependsOn(':app')
+}
+
+task clean(type: Delete) {
+    delete rootProject.buildDir
+}

+ 3 - 0
android/gradle.properties

@@ -0,0 +1,3 @@
+org.gradle.jvmargs=-Xmx1536M
+android.useAndroidX=true
+android.enableJetifier=true

+ 6 - 0
android/gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+#Fri Jun 23 08:50:38 CEST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip

+ 11 - 0
android/settings.gradle

@@ -0,0 +1,11 @@
+include ':app'
+
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
+
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
+
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"

+ 34 - 0
ios/.gitignore

@@ -0,0 +1,34 @@
+**/dgph
+*.mode1v3
+*.mode2v3
+*.moved-aside
+*.pbxuser
+*.perspectivev3
+**/*sync/
+.sconsign.dblite
+.tags*
+**/.vagrant/
+**/DerivedData/
+Icon?
+**/Pods/
+**/.symlinks/
+profile
+xcuserdata
+**/.generated/
+Flutter/App.framework
+Flutter/Flutter.framework
+Flutter/Flutter.podspec
+Flutter/Generated.xcconfig
+Flutter/ephemeral/
+Flutter/app.flx
+Flutter/app.zip
+Flutter/flutter_assets/
+Flutter/flutter_export_environment.sh
+ServiceDefinitions.json
+Runner/GeneratedPluginRegistrant.*
+
+# Exceptions to above rules.
+!default.mode1v3
+!default.mode2v3
+!default.pbxuser
+!default.perspectivev3

+ 26 - 0
ios/Flutter/AppFrameworkInfo.plist

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+  <key>CFBundleDevelopmentRegion</key>
+  <string>en</string>
+  <key>CFBundleExecutable</key>
+  <string>App</string>
+  <key>CFBundleIdentifier</key>
+  <string>io.flutter.flutter.app</string>
+  <key>CFBundleInfoDictionaryVersion</key>
+  <string>6.0</string>
+  <key>CFBundleName</key>
+  <string>App</string>
+  <key>CFBundlePackageType</key>
+  <string>FMWK</string>
+  <key>CFBundleShortVersionString</key>
+  <string>1.0</string>
+  <key>CFBundleSignature</key>
+  <string>????</string>
+  <key>CFBundleVersion</key>
+  <string>1.0</string>
+  <key>MinimumOSVersion</key>
+  <string>11.0</string>
+</dict>
+</plist>

+ 2 - 0
ios/Flutter/Debug.xcconfig

@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
+#include "Generated.xcconfig"

+ 2 - 0
ios/Flutter/Release.xcconfig

@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
+#include "Generated.xcconfig"

+ 44 - 0
ios/Podfile

@@ -0,0 +1,44 @@
+# Uncomment this line to define a global platform for your project
+# platform :ios, '11.0'
+
+# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
+ENV['COCOAPODS_DISABLE_STATS'] = 'true'
+
+project 'Runner', {
+  'Debug' => :debug,
+  'Profile' => :release,
+  'Release' => :release,
+}
+
+def flutter_root
+  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
+  unless File.exist?(generated_xcode_build_settings_path)
+    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
+  end
+
+  File.foreach(generated_xcode_build_settings_path) do |line|
+    matches = line.match(/FLUTTER_ROOT\=(.*)/)
+    return matches[1].strip if matches
+  end
+  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
+end
+
+require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
+
+flutter_ios_podfile_setup
+
+target 'Runner' do
+  use_frameworks!
+  use_modular_headers!
+
+  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
+  target 'RunnerTests' do
+    inherit! :search_paths
+  end
+end
+
+post_install do |installer|
+  installer.pods_project.targets.each do |target|
+    flutter_additional_ios_build_settings(target)
+  end
+end

+ 481 - 0
ios/Runner.xcodeproj/project.pbxproj

@@ -0,0 +1,481 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 50;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+		3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+		74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
+		97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
+		97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
+		97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		9705A1C41CF9048500538489 /* Embed Frameworks */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "";
+			dstSubfolderSpec = 10;
+			files = (
+			);
+			name = "Embed Frameworks";
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
+		1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
+		3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
+		74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
+		74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
+		7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
+		9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
+		9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
+		97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+		97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+		97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
+		97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		97C146EB1CF9000F007C117D /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		9740EEB11CF90186004384FC /* Flutter */ = {
+			isa = PBXGroup;
+			children = (
+				3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
+				9740EEB21CF90195004384FC /* Debug.xcconfig */,
+				7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+				9740EEB31CF90195004384FC /* Generated.xcconfig */,
+			);
+			name = Flutter;
+			sourceTree = "<group>";
+		};
+		97C146E51CF9000F007C117D = {
+			isa = PBXGroup;
+			children = (
+				9740EEB11CF90186004384FC /* Flutter */,
+				97C146F01CF9000F007C117D /* Runner */,
+				97C146EF1CF9000F007C117D /* Products */,
+			);
+			sourceTree = "<group>";
+		};
+		97C146EF1CF9000F007C117D /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				97C146EE1CF9000F007C117D /* Runner.app */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		97C146F01CF9000F007C117D /* Runner */ = {
+			isa = PBXGroup;
+			children = (
+				97C146FA1CF9000F007C117D /* Main.storyboard */,
+				97C146FD1CF9000F007C117D /* Assets.xcassets */,
+				97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
+				97C147021CF9000F007C117D /* Info.plist */,
+				1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
+				1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
+				74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
+				74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
+			);
+			path = Runner;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		97C146ED1CF9000F007C117D /* Runner */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
+			buildPhases = (
+				9740EEB61CF901F6004384FC /* Run Script */,
+				97C146EA1CF9000F007C117D /* Sources */,
+				97C146EB1CF9000F007C117D /* Frameworks */,
+				97C146EC1CF9000F007C117D /* Resources */,
+				9705A1C41CF9048500538489 /* Embed Frameworks */,
+				3B06AD1E1E4923F5004D2608 /* Thin Binary */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = Runner;
+			productName = Runner;
+			productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		97C146E61CF9000F007C117D /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 1300;
+				ORGANIZATIONNAME = "";
+				TargetAttributes = {
+					97C146ED1CF9000F007C117D = {
+						CreatedOnToolsVersion = 7.3.1;
+						LastSwiftMigration = 1100;
+					};
+				};
+			};
+			buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
+			compatibilityVersion = "Xcode 9.3";
+			developmentRegion = en;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+				Base,
+			);
+			mainGroup = 97C146E51CF9000F007C117D;
+			productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				97C146ED1CF9000F007C117D /* Runner */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		97C146EC1CF9000F007C117D /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
+				3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
+				97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
+				97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Thin Binary";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
+		};
+		9740EEB61CF901F6004384FC /* Run Script */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Run Script";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		97C146EA1CF9000F007C117D /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
+				1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+		97C146FA1CF9000F007C117D /* Main.storyboard */ = {
+			isa = PBXVariantGroup;
+			children = (
+				97C146FB1CF9000F007C117D /* Base */,
+			);
+			name = Main.storyboard;
+			sourceTree = "<group>";
+		};
+		97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
+			isa = PBXVariantGroup;
+			children = (
+				97C147001CF9000F007C117D /* Base */,
+			);
+			name = LaunchScreen.storyboard;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		249021D3217E4FDB00AE95B9 /* Profile */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = iphoneos;
+				SUPPORTED_PLATFORMS = iphoneos;
+				TARGETED_DEVICE_FAMILY = "1,2";
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Profile;
+		};
+		249021D4217E4FDB00AE95B9 /* Profile */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
+				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+				ENABLE_BITCODE = NO;
+				INFOPLIST_FILE = Runner/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = com.example.material3Demo;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+				SWIFT_VERSION = 5.0;
+				VERSIONING_SYSTEM = "apple-generic";
+			};
+			name = Profile;
+		};
+		97C147031CF9000F007C117D /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				MTL_ENABLE_DEBUG_INFO = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = iphoneos;
+				TARGETED_DEVICE_FAMILY = "1,2";
+			};
+			name = Debug;
+		};
+		97C147041CF9000F007C117D /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = iphoneos;
+				SUPPORTED_PLATFORMS = iphoneos;
+				SWIFT_COMPILATION_MODE = wholemodule;
+				SWIFT_OPTIMIZATION_LEVEL = "-O";
+				TARGETED_DEVICE_FAMILY = "1,2";
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Release;
+		};
+		97C147061CF9000F007C117D /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
+				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+				ENABLE_BITCODE = NO;
+				INFOPLIST_FILE = Runner/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = com.example.material3Demo;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+				SWIFT_VERSION = 5.0;
+				VERSIONING_SYSTEM = "apple-generic";
+			};
+			name = Debug;
+		};
+		97C147071CF9000F007C117D /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
+				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+				ENABLE_BITCODE = NO;
+				INFOPLIST_FILE = Runner/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = com.example.material3Demo;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+				SWIFT_VERSION = 5.0;
+				VERSIONING_SYSTEM = "apple-generic";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				97C147031CF9000F007C117D /* Debug */,
+				97C147041CF9000F007C117D /* Release */,
+				249021D3217E4FDB00AE95B9 /* Profile */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				97C147061CF9000F007C117D /* Debug */,
+				97C147071CF9000F007C117D /* Release */,
+				249021D4217E4FDB00AE95B9 /* Profile */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 97C146E61CF9000F007C117D /* Project object */;
+}

+ 7 - 0
ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "self:">
+   </FileRef>
+</Workspace>

+ 8 - 0
ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IDEDidComputeMac32BitWarning</key>
+	<true/>
+</dict>
+</plist>

+ 8 - 0
ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>PreviewsEnabled</key>
+	<false/>
+</dict>
+</plist>

+ 87 - 0
ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme

@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1300"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+               BuildableName = "Runner.app"
+               BlueprintName = "Runner"
+               ReferencedContainer = "container:Runner.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+            BuildableName = "Runner.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+      <Testables>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+            BuildableName = "Runner.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Profile"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+            BuildableName = "Runner.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

+ 7 - 0
ios/Runner.xcworkspace/contents.xcworkspacedata

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "group:Runner.xcodeproj">
+   </FileRef>
+</Workspace>

+ 8 - 0
ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IDEDidComputeMac32BitWarning</key>
+	<true/>
+</dict>
+</plist>

+ 8 - 0
ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>PreviewsEnabled</key>
+	<false/>
+</dict>
+</plist>

+ 13 - 0
ios/Runner/AppDelegate.swift

@@ -0,0 +1,13 @@
+import UIKit
+import Flutter
+
+@UIApplicationMain
+@objc class AppDelegate: FlutterAppDelegate {
+  override func application(
+    _ application: UIApplication,
+    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
+  ) -> Bool {
+    GeneratedPluginRegistrant.register(with: self)
+    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
+  }
+}

+ 122 - 0
ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json

@@ -0,0 +1,122 @@
+{
+  "images" : [
+    {
+      "size" : "20x20",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-20x20@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "20x20",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-20x20@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-29x29@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-29x29@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-29x29@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-40x40@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-40x40@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "size" : "60x60",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-60x60@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "60x60",
+      "idiom" : "iphone",
+      "filename" : "Icon-App-60x60@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "size" : "20x20",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-20x20@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "20x20",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-20x20@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-29x29@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-29x29@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-40x40@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-40x40@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "76x76",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-76x76@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "76x76",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-76x76@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "83.5x83.5",
+      "idiom" : "ipad",
+      "filename" : "Icon-App-83.5x83.5@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "1024x1024",
+      "idiom" : "ios-marketing",
+      "filename" : "Icon-App-1024x1024@1x.png",
+      "scale" : "1x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png


BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png


+ 23 - 0
ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json

@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "LaunchImage.png",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "LaunchImage@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "LaunchImage@3x.png",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png


BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png


BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png


+ 5 - 0
ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md

@@ -0,0 +1,5 @@
+# Launch Screen Assets
+
+You can customize the launch screen with your own desired assets by replacing the image files in this directory.
+
+You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.

+ 37 - 0
ios/Runner/Base.lproj/LaunchScreen.storyboard

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
+    </dependencies>
+    <scenes>
+        <!--View Controller-->
+        <scene sceneID="EHf-IW-A2E">
+            <objects>
+                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
+                        <viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
+                            </imageView>
+                        </subviews>
+                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                        <constraints>
+                            <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
+                            <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
+                        </constraints>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="53" y="375"/>
+        </scene>
+    </scenes>
+    <resources>
+        <image name="LaunchImage" width="168" height="185"/>
+    </resources>
+</document>

+ 26 - 0
ios/Runner/Base.lproj/Main.storyboard

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
+    </dependencies>
+    <scenes>
+        <!--Flutter View Controller-->
+        <scene sceneID="tne-QT-ifu">
+            <objects>
+                <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
+                        <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
+                        <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
+            </objects>
+        </scene>
+    </scenes>
+</document>

+ 49 - 0
ios/Runner/Info.plist

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>$(DEVELOPMENT_LANGUAGE)</string>
+	<key>CFBundleDisplayName</key>
+	<string>Material 3 Demo</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>material_3_demo</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>$(FLUTTER_BUILD_NAME)</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>$(FLUTTER_BUILD_NUMBER)</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>UILaunchStoryboardName</key>
+	<string>LaunchScreen</string>
+	<key>UIMainStoryboardFile</key>
+	<string>Main</string>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UIViewControllerBasedStatusBarAppearance</key>
+	<false/>
+	<key>CADisableMinimumFrameDurationOnPhone</key>
+	<true/>
+</dict>
+</plist>

+ 1 - 0
ios/Runner/Runner-Bridging-Header.h

@@ -0,0 +1 @@
+#import "GeneratedPluginRegistrant.h"

+ 339 - 0
lib/color_palettes_screen.dart

@@ -0,0 +1,339 @@
+// Copyright 2021 The Flutter team. 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/gestures.dart';
+import 'package:flutter/material.dart';
+import 'package:url_launcher/url_launcher.dart';
+
+const Widget divider = SizedBox(height: 10);
+
+// If screen content width is greater or equal to this value, the light and dark
+// color schemes will be displayed in a column. Otherwise, they will
+// be displayed in a row.
+const double narrowScreenWidthThreshold = 400;
+
+class ColorPalettesScreen extends StatelessWidget {
+  const ColorPalettesScreen({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    Color selectedColor = Theme.of(context).primaryColor;
+    ThemeData lightTheme = ThemeData(
+      colorSchemeSeed: selectedColor,
+      brightness: Brightness.light,
+    );
+    ThemeData darkTheme = ThemeData(
+      colorSchemeSeed: selectedColor,
+      brightness: Brightness.dark,
+    );
+
+    Widget schemeLabel(String brightness) {
+      return Padding(
+        padding: const EdgeInsets.symmetric(vertical: 15),
+        child: Text(
+          brightness,
+          style: const TextStyle(fontWeight: FontWeight.bold),
+        ),
+      );
+    }
+
+    Widget schemeView(ThemeData theme) {
+      return Padding(
+        padding: const EdgeInsets.symmetric(horizontal: 15),
+        child: ColorSchemeView(
+          colorScheme: theme.colorScheme,
+        ),
+      );
+    }
+
+    Widget dynamicColorNotice() => RichText(
+          textAlign: TextAlign.center,
+          text: TextSpan(
+            style: Theme.of(context).textTheme.bodySmall,
+            children: [
+              const TextSpan(
+                  text: 'To create color schemes based on a '
+                      'platform\'s implementation of dynamic color, '
+                      'use the '),
+              TextSpan(
+                text: 'dynamic_color',
+                style: const TextStyle(decoration: TextDecoration.underline),
+                recognizer: TapGestureRecognizer()
+                  ..onTap = () async {
+                    final url = Uri.parse(
+                      'https://pub.dev/packages/dynamic_color',
+                    );
+                    if (!await launchUrl(url)) {
+                      throw Exception('Could not launch $url');
+                    }
+                  },
+              ),
+              const TextSpan(text: ' package.'),
+            ],
+          ),
+        );
+
+    return Expanded(
+      child: LayoutBuilder(builder: (context, constraints) {
+        if (constraints.maxWidth < narrowScreenWidthThreshold) {
+          return SingleChildScrollView(
+            child: Column(
+              children: [
+                dynamicColorNotice(),
+                divider,
+                schemeLabel('Light ColorScheme'),
+                schemeView(lightTheme),
+                divider,
+                divider,
+                schemeLabel('Dark ColorScheme'),
+                schemeView(darkTheme),
+              ],
+            ),
+          );
+        } else {
+          return SingleChildScrollView(
+            child: Padding(
+              padding: const EdgeInsets.only(top: 5),
+              child: Column(
+                children: [
+                  dynamicColorNotice(),
+                  Row(
+                    children: [
+                      Expanded(
+                        child: Column(
+                          children: [
+                            schemeLabel('Light ColorScheme'),
+                            schemeView(lightTheme),
+                          ],
+                        ),
+                      ),
+                      Expanded(
+                        child: Column(
+                          children: [
+                            schemeLabel('Dark ColorScheme'),
+                            schemeView(darkTheme),
+                          ],
+                        ),
+                      ),
+                    ],
+                  ),
+                ],
+              ),
+            ),
+          );
+        }
+      }),
+    );
+  }
+}
+
+class ColorSchemeView extends StatelessWidget {
+  const ColorSchemeView({super.key, required this.colorScheme});
+
+  final ColorScheme colorScheme;
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        ColorGroup(children: [
+          ColorChip(
+            label: 'primary',
+            color: colorScheme.primary,
+            onColor: colorScheme.onPrimary,
+          ),
+          ColorChip(
+              label: 'onPrimary',
+              color: colorScheme.onPrimary,
+              onColor: colorScheme.primary),
+          ColorChip(
+            label: 'primaryContainer',
+            color: colorScheme.primaryContainer,
+            onColor: colorScheme.onPrimaryContainer,
+          ),
+          ColorChip(
+            label: 'onPrimaryContainer',
+            color: colorScheme.onPrimaryContainer,
+            onColor: colorScheme.primaryContainer,
+          ),
+        ]),
+        divider,
+        ColorGroup(children: [
+          ColorChip(
+            label: 'secondary',
+            color: colorScheme.secondary,
+            onColor: colorScheme.onSecondary,
+          ),
+          ColorChip(
+            label: 'onSecondary',
+            color: colorScheme.onSecondary,
+            onColor: colorScheme.secondary,
+          ),
+          ColorChip(
+            label: 'secondaryContainer',
+            color: colorScheme.secondaryContainer,
+            onColor: colorScheme.onSecondaryContainer,
+          ),
+          ColorChip(
+              label: 'onSecondaryContainer',
+              color: colorScheme.onSecondaryContainer,
+              onColor: colorScheme.secondaryContainer),
+        ]),
+        divider,
+        ColorGroup(
+          children: [
+            ColorChip(
+                label: 'tertiary',
+                color: colorScheme.tertiary,
+                onColor: colorScheme.onTertiary),
+            ColorChip(
+                label: 'onTertiary',
+                color: colorScheme.onTertiary,
+                onColor: colorScheme.tertiary),
+            ColorChip(
+                label: 'tertiaryContainer',
+                color: colorScheme.tertiaryContainer,
+                onColor: colorScheme.onTertiaryContainer),
+            ColorChip(
+                label: 'onTertiaryContainer',
+                color: colorScheme.onTertiaryContainer,
+                onColor: colorScheme.tertiaryContainer),
+          ],
+        ),
+        divider,
+        ColorGroup(
+          children: [
+            ColorChip(
+                label: 'error',
+                color: colorScheme.error,
+                onColor: colorScheme.onError),
+            ColorChip(
+                label: 'onError',
+                color: colorScheme.onError,
+                onColor: colorScheme.error),
+            ColorChip(
+                label: 'errorContainer',
+                color: colorScheme.errorContainer,
+                onColor: colorScheme.onErrorContainer),
+            ColorChip(
+                label: 'onErrorContainer',
+                color: colorScheme.onErrorContainer,
+                onColor: colorScheme.errorContainer),
+          ],
+        ),
+        divider,
+        ColorGroup(
+          children: [
+            ColorChip(
+                label: 'background',
+                color: colorScheme.background,
+                onColor: colorScheme.onBackground),
+            ColorChip(
+                label: 'onBackground',
+                color: colorScheme.onBackground,
+                onColor: colorScheme.background),
+          ],
+        ),
+        divider,
+        ColorGroup(
+          children: [
+            ColorChip(
+                label: 'surface',
+                color: colorScheme.surface,
+                onColor: colorScheme.onSurface),
+            ColorChip(
+                label: 'onSurface',
+                color: colorScheme.onSurface,
+                onColor: colorScheme.surface),
+            ColorChip(
+                label: 'surfaceVariant',
+                color: colorScheme.surfaceVariant,
+                onColor: colorScheme.onSurfaceVariant),
+            ColorChip(
+                label: 'onSurfaceVariant',
+                color: colorScheme.onSurfaceVariant,
+                onColor: colorScheme.surfaceVariant),
+          ],
+        ),
+        divider,
+        ColorGroup(
+          children: [
+            ColorChip(label: 'outline', color: colorScheme.outline),
+            ColorChip(label: 'shadow', color: colorScheme.shadow),
+            ColorChip(
+                label: 'inverseSurface',
+                color: colorScheme.inverseSurface,
+                onColor: colorScheme.onInverseSurface),
+            ColorChip(
+                label: 'onInverseSurface',
+                color: colorScheme.onInverseSurface,
+                onColor: colorScheme.inverseSurface),
+            ColorChip(
+                label: 'inversePrimary',
+                color: colorScheme.inversePrimary,
+                onColor: colorScheme.primary),
+          ],
+        ),
+      ],
+    );
+  }
+}
+
+class ColorGroup extends StatelessWidget {
+  const ColorGroup({super.key, required this.children});
+
+  final List<Widget> children;
+
+  @override
+  Widget build(BuildContext context) {
+    return RepaintBoundary(
+      child: Card(
+        clipBehavior: Clip.antiAlias,
+        child: Column(
+          children: children,
+        ),
+      ),
+    );
+  }
+}
+
+class ColorChip extends StatelessWidget {
+  const ColorChip({
+    super.key,
+    required this.color,
+    required this.label,
+    this.onColor,
+  });
+
+  final Color color;
+  final Color? onColor;
+  final String label;
+
+  static Color contrastColor(Color color) {
+    final brightness = ThemeData.estimateBrightnessForColor(color);
+    switch (brightness) {
+      case Brightness.dark:
+        return Colors.white;
+      case Brightness.light:
+        return Colors.black;
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final Color labelColor = onColor ?? contrastColor(color);
+
+    return Container(
+      color: color,
+      child: Padding(
+        padding: const EdgeInsets.all(16),
+        child: Row(
+          children: [
+            Expanded(child: Text(label, style: TextStyle(color: labelColor))),
+          ],
+        ),
+      ),
+    );
+  }
+}

+ 2308 - 0
lib/component_screen.dart

@@ -0,0 +1,2308 @@
+// Copyright 2021 The Flutter team. 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/material.dart';
+import 'package:flutter/services.dart';
+
+const rowDivider = SizedBox(width: 20);
+const colDivider = SizedBox(height: 10);
+const tinySpacing = 3.0;
+const smallSpacing = 10.0;
+const double cardWidth = 115;
+const double widthConstraint = 450;
+
+class FirstComponentList extends StatelessWidget {
+  const FirstComponentList({
+    super.key,
+    required this.showNavBottomBar,
+    required this.scaffoldKey,
+    required this.showSecondList,
+  });
+
+  final bool showNavBottomBar;
+  final GlobalKey<ScaffoldState> scaffoldKey;
+  final bool showSecondList;
+
+  @override
+  Widget build(BuildContext context) {
+    // Fully traverse this list before moving on.
+    return FocusTraversalGroup(
+      child: ListView(
+        padding: showSecondList
+            ? const EdgeInsetsDirectional.only(end: smallSpacing)
+            : EdgeInsets.zero,
+        children: [
+          const Actions(),
+          colDivider,
+          const Communication(),
+          colDivider,
+          const Containment(),
+          if (!showSecondList) ...[
+            colDivider,
+            Navigation(scaffoldKey: scaffoldKey),
+            colDivider,
+            const Selection(),
+            colDivider,
+            const TextInputs()
+          ],
+        ],
+      ),
+    );
+  }
+}
+
+class SecondComponentList extends StatelessWidget {
+  const SecondComponentList({
+    super.key,
+    required this.scaffoldKey,
+  });
+
+  final GlobalKey<ScaffoldState> scaffoldKey;
+
+  @override
+  Widget build(BuildContext context) {
+    // Fully traverse this list before moving on.
+    return FocusTraversalGroup(
+      child: ListView(
+        padding: const EdgeInsetsDirectional.only(end: smallSpacing),
+        children: <Widget>[
+          Navigation(scaffoldKey: scaffoldKey),
+          colDivider,
+          const Selection(),
+          colDivider,
+          const TextInputs(),
+        ],
+      ),
+    );
+  }
+}
+
+class Actions extends StatelessWidget {
+  const Actions({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return const ComponentGroupDecoration(label: 'Actions', children: <Widget>[
+      Buttons(),
+      FloatingActionButtons(),
+      IconToggleButtons(),
+      SegmentedButtons(),
+    ]);
+  }
+}
+
+class Communication extends StatelessWidget {
+  const Communication({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return const ComponentGroupDecoration(label: 'Communication', children: [
+      NavigationBars(
+        selectedIndex: 1,
+        isExampleBar: true,
+        isBadgeExample: true,
+      ),
+      ProgressIndicators(),
+      SnackBarSection(),
+    ]);
+  }
+}
+
+class Containment extends StatelessWidget {
+  const Containment({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return const ComponentGroupDecoration(label: 'Containment', children: [
+      BottomSheetSection(),
+      Cards(),
+      Dialogs(),
+      Dividers(),
+      // TODO: Add Lists, https://github.com/flutter/flutter/issues/114006
+      // TODO: Add Side sheets, https://github.com/flutter/flutter/issues/119328
+    ]);
+  }
+}
+
+class Navigation extends StatelessWidget {
+  const Navigation({super.key, required this.scaffoldKey});
+
+  final GlobalKey<ScaffoldState> scaffoldKey;
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentGroupDecoration(label: 'Navigation', children: [
+      const BottomAppBars(),
+      const NavigationBars(
+        selectedIndex: 0,
+        isExampleBar: true,
+      ),
+      NavigationDrawers(scaffoldKey: scaffoldKey),
+      const NavigationRails(),
+      // TODO: Add Search https://github.com/flutter/flutter/issues/117483
+      const Tabs(),
+      const TopAppBars(),
+    ]);
+  }
+}
+
+class Selection extends StatelessWidget {
+  const Selection({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return const ComponentGroupDecoration(label: 'Selection', children: [
+      Checkboxes(),
+      Chips(),
+      // TODO: Add Date pickers https://github.com/flutter/flutter/issues/101481
+      Menus(),
+      Radios(),
+      Sliders(),
+      Switches(),
+      // TODO: Add Time pickers https://github.com/flutter/flutter/issues/101480
+    ]);
+  }
+}
+
+class TextInputs extends StatelessWidget {
+  const TextInputs({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return const ComponentGroupDecoration(
+      label: 'Text inputs',
+      children: [TextFields()],
+    );
+  }
+}
+
+class Buttons extends StatefulWidget {
+  const Buttons({super.key});
+
+  @override
+  State<Buttons> createState() => _ButtonsState();
+}
+
+class _ButtonsState extends State<Buttons> {
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Common buttons',
+      tooltipMessage:
+          'Use ElevatedButton, FilledButton, FilledButton.tonal, OutlinedButton, or TextButton',
+      child: SingleChildScrollView(
+        scrollDirection: Axis.horizontal,
+        child: Row(
+          mainAxisAlignment: MainAxisAlignment.spaceAround,
+          children: const <Widget>[
+            ButtonsWithoutIcon(isDisabled: false),
+            ButtonsWithIcon(),
+            ButtonsWithoutIcon(isDisabled: true),
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+class ButtonsWithoutIcon extends StatelessWidget {
+  final bool isDisabled;
+
+  const ButtonsWithoutIcon({super.key, required this.isDisabled});
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: const EdgeInsets.symmetric(horizontal: 5.0),
+      child: IntrinsicWidth(
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.stretch,
+          children: <Widget>[
+            ElevatedButton(
+              onPressed: isDisabled ? null : () {},
+              child: const Text('Elevated'),
+            ),
+            colDivider,
+            FilledButton(
+              onPressed: isDisabled ? null : () {},
+              child: const Text('Filled'),
+            ),
+            colDivider,
+            FilledButton.tonal(
+              onPressed: isDisabled ? null : () {},
+              child: const Text('Filled tonal'),
+            ),
+            colDivider,
+            OutlinedButton(
+              onPressed: isDisabled ? null : () {},
+              child: const Text('Outlined'),
+            ),
+            colDivider,
+            TextButton(
+              onPressed: isDisabled ? null : () {},
+              child: const Text('Text'),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+class ButtonsWithIcon extends StatelessWidget {
+  const ButtonsWithIcon({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: const EdgeInsets.symmetric(horizontal: 10.0),
+      child: IntrinsicWidth(
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.stretch,
+          children: <Widget>[
+            ElevatedButton.icon(
+              onPressed: () {},
+              icon: const Icon(Icons.add),
+              label: const Text('Icon'),
+            ),
+            colDivider,
+            FilledButton.icon(
+              onPressed: () {},
+              label: const Text('Icon'),
+              icon: const Icon(Icons.add),
+            ),
+            colDivider,
+            FilledButton.tonalIcon(
+              onPressed: () {},
+              label: const Text('Icon'),
+              icon: const Icon(Icons.add),
+            ),
+            colDivider,
+            OutlinedButton.icon(
+              onPressed: () {},
+              icon: const Icon(Icons.add),
+              label: const Text('Icon'),
+            ),
+            colDivider,
+            TextButton.icon(
+              onPressed: () {},
+              icon: const Icon(Icons.add),
+              label: const Text('Icon'),
+            )
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+class FloatingActionButtons extends StatelessWidget {
+  const FloatingActionButtons({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Floating action buttons',
+      tooltipMessage:
+          'Use FloatingActionButton or FloatingActionButton.extended',
+      child: Wrap(
+        crossAxisAlignment: WrapCrossAlignment.center,
+        runSpacing: smallSpacing,
+        spacing: smallSpacing,
+        children: [
+          FloatingActionButton.small(
+            onPressed: () {},
+            tooltip: 'Small',
+            child: const Icon(Icons.add),
+          ),
+          FloatingActionButton.extended(
+            onPressed: () {},
+            tooltip: 'Extended',
+            icon: const Icon(Icons.add),
+            label: const Text('Create'),
+          ),
+          FloatingActionButton(
+            onPressed: () {},
+            tooltip: 'Standard',
+            child: const Icon(Icons.add),
+          ),
+          FloatingActionButton.large(
+            onPressed: () {},
+            tooltip: 'Large',
+            child: const Icon(Icons.add),
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+class Cards extends StatelessWidget {
+  const Cards({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Cards',
+      tooltipMessage: 'Use Card',
+      child: Wrap(
+        alignment: WrapAlignment.spaceEvenly,
+        children: [
+          SizedBox(
+            width: cardWidth,
+            child: Card(
+              child: Container(
+                padding: const EdgeInsets.fromLTRB(10, 5, 5, 10),
+                child: Column(
+                  children: [
+                    Align(
+                      alignment: Alignment.topRight,
+                      child: IconButton(
+                        icon: const Icon(Icons.more_vert),
+                        onPressed: () {},
+                      ),
+                    ),
+                    const SizedBox(height: 20),
+                    const Align(
+                      alignment: Alignment.bottomLeft,
+                      child: Text('Elevated'),
+                    )
+                  ],
+                ),
+              ),
+            ),
+          ),
+          SizedBox(
+            width: cardWidth,
+            child: Card(
+              color: Theme.of(context).colorScheme.surfaceVariant,
+              elevation: 0,
+              child: Container(
+                padding: const EdgeInsets.fromLTRB(10, 5, 5, 10),
+                child: Column(
+                  children: [
+                    Align(
+                      alignment: Alignment.topRight,
+                      child: IconButton(
+                        icon: const Icon(Icons.more_vert),
+                        onPressed: () {},
+                      ),
+                    ),
+                    const SizedBox(height: 20),
+                    const Align(
+                      alignment: Alignment.bottomLeft,
+                      child: Text('Filled'),
+                    )
+                  ],
+                ),
+              ),
+            ),
+          ),
+          SizedBox(
+            width: cardWidth,
+            child: Card(
+              elevation: 0,
+              shape: RoundedRectangleBorder(
+                side: BorderSide(
+                  color: Theme.of(context).colorScheme.outline,
+                ),
+                borderRadius: const BorderRadius.all(Radius.circular(12)),
+              ),
+              child: Container(
+                padding: const EdgeInsets.fromLTRB(10, 5, 5, 10),
+                child: Column(
+                  children: [
+                    Align(
+                      alignment: Alignment.topRight,
+                      child: IconButton(
+                        icon: const Icon(Icons.more_vert),
+                        onPressed: () {},
+                      ),
+                    ),
+                    const SizedBox(height: 20),
+                    const Align(
+                      alignment: Alignment.bottomLeft,
+                      child: Text('Outlined'),
+                    )
+                  ],
+                ),
+              ),
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+class _ClearButton extends StatelessWidget {
+  const _ClearButton({required this.controller});
+
+  final TextEditingController controller;
+
+  @override
+  Widget build(BuildContext context) => IconButton(
+        icon: const Icon(Icons.clear),
+        onPressed: () => controller.clear(),
+      );
+}
+
+class TextFields extends StatefulWidget {
+  const TextFields({super.key});
+
+  @override
+  State<TextFields> createState() => _TextFieldsState();
+}
+
+class _TextFieldsState extends State<TextFields> {
+  final TextEditingController _controllerFilled = TextEditingController();
+  final TextEditingController _controllerOutlined = TextEditingController();
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Text fields',
+      tooltipMessage: 'Use TextField with different InputDecoration',
+      child: Column(
+        mainAxisAlignment: MainAxisAlignment.start,
+        children: [
+          Padding(
+            padding: const EdgeInsets.all(smallSpacing),
+            child: TextField(
+              controller: _controllerFilled,
+              decoration: InputDecoration(
+                prefixIcon: const Icon(Icons.search),
+                suffixIcon: _ClearButton(controller: _controllerFilled),
+                labelText: 'Filled',
+                hintText: 'hint text',
+                helperText: 'supporting text',
+                filled: true,
+              ),
+            ),
+          ),
+          Padding(
+            padding: const EdgeInsets.all(smallSpacing),
+            child: Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Flexible(
+                  child: SizedBox(
+                    width: 200,
+                    child: TextField(
+                      maxLength: 10,
+                      maxLengthEnforcement: MaxLengthEnforcement.none,
+                      controller: _controllerFilled,
+                      decoration: InputDecoration(
+                        prefixIcon: const Icon(Icons.search),
+                        suffixIcon: _ClearButton(controller: _controllerFilled),
+                        labelText: 'Filled',
+                        hintText: 'hint text',
+                        helperText: 'supporting text',
+                        filled: true,
+                        errorText: 'error text',
+                      ),
+                    ),
+                  ),
+                ),
+                const SizedBox(width: smallSpacing),
+                Flexible(
+                  child: SizedBox(
+                    width: 200,
+                    child: TextField(
+                      controller: _controllerFilled,
+                      enabled: false,
+                      decoration: InputDecoration(
+                        prefixIcon: const Icon(Icons.search),
+                        suffixIcon: _ClearButton(controller: _controllerFilled),
+                        labelText: 'Disabled',
+                        hintText: 'hint text',
+                        helperText: 'supporting text',
+                        filled: true,
+                      ),
+                    ),
+                  ),
+                ),
+              ],
+            ),
+          ),
+          Padding(
+            padding: const EdgeInsets.all(smallSpacing),
+            child: TextField(
+              controller: _controllerOutlined,
+              decoration: InputDecoration(
+                prefixIcon: const Icon(Icons.search),
+                suffixIcon: _ClearButton(controller: _controllerOutlined),
+                labelText: 'Outlined',
+                hintText: 'hint text',
+                helperText: 'supporting text',
+                border: const OutlineInputBorder(),
+              ),
+            ),
+          ),
+          Padding(
+              padding: const EdgeInsets.all(smallSpacing),
+              child: Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    Flexible(
+                      child: SizedBox(
+                        width: 200,
+                        child: TextField(
+                          controller: _controllerOutlined,
+                          decoration: InputDecoration(
+                            prefixIcon: const Icon(Icons.search),
+                            suffixIcon:
+                                _ClearButton(controller: _controllerOutlined),
+                            labelText: 'Outlined',
+                            hintText: 'hint text',
+                            helperText: 'supporting text',
+                            errorText: 'error text',
+                            border: const OutlineInputBorder(),
+                            filled: true,
+                          ),
+                        ),
+                      ),
+                    ),
+                    const SizedBox(width: smallSpacing),
+                    Flexible(
+                      child: SizedBox(
+                        width: 200,
+                        child: TextField(
+                          controller: _controllerOutlined,
+                          enabled: false,
+                          decoration: InputDecoration(
+                            prefixIcon: const Icon(Icons.search),
+                            suffixIcon:
+                                _ClearButton(controller: _controllerOutlined),
+                            labelText: 'Disabled',
+                            hintText: 'hint text',
+                            helperText: 'supporting text',
+                            border: const OutlineInputBorder(),
+                            filled: true,
+                          ),
+                        ),
+                      ),
+                    ),
+                  ])),
+        ],
+      ),
+    );
+  }
+}
+
+class Dialogs extends StatefulWidget {
+  const Dialogs({super.key});
+
+  @override
+  State<Dialogs> createState() => _DialogsState();
+}
+
+class _DialogsState extends State<Dialogs> {
+  void openDialog(BuildContext context) {
+    showDialog<void>(
+      context: context,
+      builder: (context) => AlertDialog(
+        title: const Text('What is a dialog?'),
+        content: const Text(
+            'A dialog is a type of modal window that appears in front of app content to provide critical information, or prompt for a decision to be made.'),
+        actions: <Widget>[
+          TextButton(
+            child: const Text('Okay'),
+            onPressed: () => Navigator.of(context).pop(),
+          ),
+          FilledButton(
+            child: const Text('Dismiss'),
+            onPressed: () => Navigator.of(context).pop(),
+          ),
+        ],
+      ),
+    );
+  }
+
+  void openFullscreenDialog(BuildContext context) {
+    showDialog<void>(
+      context: context,
+      builder: (context) => Dialog.fullscreen(
+        child: Padding(
+          padding: const EdgeInsets.all(20.0),
+          child: Scaffold(
+            appBar: AppBar(
+              title: const Text('Full-screen dialog'),
+              centerTitle: false,
+              leading: IconButton(
+                icon: const Icon(Icons.close),
+                onPressed: () => Navigator.of(context).pop(),
+              ),
+              actions: [
+                TextButton(
+                  child: const Text('Close'),
+                  onPressed: () => Navigator.of(context).pop(),
+                ),
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Dialog',
+      tooltipMessage:
+          'Use showDialog with Dialog.fullscreen, AlertDialog, or SimpleDialog',
+      child: Wrap(
+        alignment: WrapAlignment.spaceBetween,
+        children: [
+          TextButton(
+            child: const Text(
+              'Show dialog',
+              style: TextStyle(fontWeight: FontWeight.bold),
+            ),
+            onPressed: () => openDialog(context),
+          ),
+          TextButton(
+            child: const Text(
+              'Show full-screen dialog',
+              style: TextStyle(fontWeight: FontWeight.bold),
+            ),
+            onPressed: () => openFullscreenDialog(context),
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+class Dividers extends StatelessWidget {
+  const Dividers({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Dividers',
+      tooltipMessage: 'Use Divider or VerticalDivider',
+      child: Column(
+        children: const <Widget>[
+          Divider(key: Key('divider')),
+        ],
+      ),
+    );
+  }
+}
+
+class Switches extends StatelessWidget {
+  const Switches({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Switches',
+      tooltipMessage: 'Use SwitchListTile or Switch',
+      child: Column(
+        children: const <Widget>[
+          SwitchRow(isEnabled: true),
+          SwitchRow(isEnabled: false),
+        ],
+      ),
+    );
+  }
+}
+
+class SwitchRow extends StatefulWidget {
+  const SwitchRow({super.key, required this.isEnabled});
+
+  final bool isEnabled;
+
+  @override
+  State<SwitchRow> createState() => _SwitchRowState();
+}
+
+class _SwitchRowState extends State<SwitchRow> {
+  bool value0 = false;
+  bool value1 = true;
+
+  final MaterialStateProperty<Icon?> thumbIcon =
+      MaterialStateProperty.resolveWith<Icon?>((states) {
+    if (states.contains(MaterialState.selected)) {
+      return const Icon(Icons.check);
+    }
+    return const Icon(Icons.close);
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Row(
+      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+      children: <Widget>[
+        // TODO: use SwitchListTile when thumbIcon is available https://github.com/flutter/flutter/issues/118616
+        Switch(
+          value: value0,
+          onChanged: widget.isEnabled
+              ? (value) {
+                  setState(() {
+                    value0 = value;
+                  });
+                }
+              : null,
+        ),
+        Switch(
+          thumbIcon: thumbIcon,
+          value: value1,
+          onChanged: widget.isEnabled
+              ? (value) {
+                  setState(() {
+                    value1 = value;
+                  });
+                }
+              : null,
+        ),
+      ],
+    );
+  }
+}
+
+class Checkboxes extends StatefulWidget {
+  const Checkboxes({super.key});
+
+  @override
+  State<Checkboxes> createState() => _CheckboxesState();
+}
+
+class _CheckboxesState extends State<Checkboxes> {
+  bool? isChecked0 = true;
+  bool? isChecked1;
+  bool? isChecked2 = false;
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Checkboxes',
+      tooltipMessage: 'Use CheckboxListTile or Checkbox',
+      child: Column(
+        children: <Widget>[
+          CheckboxListTile(
+            tristate: true,
+            value: isChecked0,
+            title: const Text('Option 1'),
+            onChanged: (value) {
+              setState(() {
+                isChecked0 = value;
+              });
+            },
+          ),
+          CheckboxListTile(
+            tristate: true,
+            value: isChecked1,
+            title: const Text('Option 2'),
+            onChanged: (value) {
+              setState(() {
+                isChecked1 = value;
+              });
+            },
+          ),
+          CheckboxListTile(
+            tristate: true,
+            value: isChecked2,
+            title: const Text('Option 3'),
+            // TODO: showcase error state https://github.com/flutter/flutter/issues/118616
+            onChanged: (value) {
+              setState(() {
+                isChecked2 = value;
+              });
+            },
+          ),
+          const CheckboxListTile(
+            tristate: true,
+            title: Text('Option 4'),
+            value: true,
+            onChanged: null,
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+enum Value { first, second }
+
+class Radios extends StatefulWidget {
+  const Radios({super.key});
+
+  @override
+  State<Radios> createState() => _RadiosState();
+}
+
+enum Options { option1, option2, option3 }
+
+class _RadiosState extends State<Radios> {
+  Options? _selectedOption = Options.option1;
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Radio buttons',
+      tooltipMessage: 'Use RadioListTile<T> or Radio<T>',
+      child: Column(
+        children: <Widget>[
+          RadioListTile<Options>(
+            title: const Text('Option 1'),
+            value: Options.option1,
+            groupValue: _selectedOption,
+            onChanged: (value) {
+              setState(() {
+                _selectedOption = value;
+              });
+            },
+          ),
+          RadioListTile<Options>(
+            title: const Text('Option 2'),
+            value: Options.option2,
+            groupValue: _selectedOption,
+            onChanged: (value) {
+              setState(() {
+                _selectedOption = value;
+              });
+            },
+          ),
+          RadioListTile<Options>(
+            title: const Text('Option 3'),
+            value: Options.option3,
+            groupValue: _selectedOption,
+            onChanged: null,
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+class ProgressIndicators extends StatefulWidget {
+  const ProgressIndicators({super.key});
+
+  @override
+  State<ProgressIndicators> createState() => _ProgressIndicatorsState();
+}
+
+class _ProgressIndicatorsState extends State<ProgressIndicators> {
+  bool playProgressIndicator = false;
+
+  @override
+  Widget build(BuildContext context) {
+    final double? progressValue = playProgressIndicator ? null : 0.7;
+
+    return ComponentDecoration(
+      label: 'Progress indicators',
+      tooltipMessage:
+          'Use CircularProgressIndicator or LinearProgressIndicator',
+      child: Column(
+        children: <Widget>[
+          Row(
+            children: [
+              IconButton(
+                isSelected: playProgressIndicator,
+                selectedIcon: const Icon(Icons.pause),
+                icon: const Icon(Icons.play_arrow),
+                onPressed: () {
+                  setState(() {
+                    playProgressIndicator = !playProgressIndicator;
+                  });
+                },
+              ),
+              Expanded(
+                child: Row(
+                  children: <Widget>[
+                    rowDivider,
+                    CircularProgressIndicator(
+                      value: progressValue,
+                    ),
+                    rowDivider,
+                    Expanded(
+                      child: LinearProgressIndicator(
+                        value: progressValue,
+                      ),
+                    ),
+                    rowDivider,
+                  ],
+                ),
+              ),
+            ],
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+const List<NavigationDestination> appBarDestinations = [
+  NavigationDestination(
+    tooltip: '',
+    icon: Icon(Icons.widgets_outlined),
+    label: 'Components',
+    selectedIcon: Icon(Icons.widgets),
+  ),
+  NavigationDestination(
+    tooltip: '',
+    icon: Icon(Icons.format_paint_outlined),
+    label: 'Color',
+    selectedIcon: Icon(Icons.format_paint),
+  ),
+  NavigationDestination(
+    tooltip: '',
+    icon: Icon(Icons.text_snippet_outlined),
+    label: 'Typography',
+    selectedIcon: Icon(Icons.text_snippet),
+  ),
+  NavigationDestination(
+    tooltip: '',
+    icon: Icon(Icons.invert_colors_on_outlined),
+    label: 'Elevation',
+    selectedIcon: Icon(Icons.opacity),
+  )
+];
+
+const List<Widget> exampleBarDestinations = [
+  NavigationDestination(
+    tooltip: '',
+    icon: Icon(Icons.explore_outlined),
+    label: 'Explore',
+    selectedIcon: Icon(Icons.explore),
+  ),
+  NavigationDestination(
+    tooltip: '',
+    icon: Icon(Icons.pets_outlined),
+    label: 'Pets',
+    selectedIcon: Icon(Icons.pets),
+  ),
+  NavigationDestination(
+    tooltip: '',
+    icon: Icon(Icons.account_box_outlined),
+    label: 'Account',
+    selectedIcon: Icon(Icons.account_box),
+  )
+];
+
+List<Widget> barWithBadgeDestinations = [
+  NavigationDestination(
+    tooltip: '',
+    icon: Badge.count(count: 1000, child: const Icon(Icons.mail_outlined)),
+    label: 'Mail',
+    selectedIcon: Badge.count(count: 1000, child: const Icon(Icons.mail)),
+  ),
+  const NavigationDestination(
+    tooltip: '',
+    icon: Badge(label: Text('10'), child: Icon(Icons.chat_bubble_outline)),
+    label: 'Chat',
+    selectedIcon: Badge(label: Text('10'), child: Icon(Icons.chat_bubble)),
+  ),
+  const NavigationDestination(
+    tooltip: '',
+    icon: Badge(child: Icon(Icons.group_outlined)),
+    label: 'Rooms',
+    selectedIcon: Badge(child: Icon(Icons.group_rounded)),
+  ),
+  NavigationDestination(
+    tooltip: '',
+    icon: Badge.count(count: 3, child: const Icon(Icons.videocam_outlined)),
+    label: 'Meet',
+    selectedIcon: Badge.count(count: 3, child: const Icon(Icons.videocam)),
+  )
+];
+
+class NavigationBars extends StatefulWidget {
+  const NavigationBars({
+    super.key,
+    this.onSelectItem,
+    required this.selectedIndex,
+    required this.isExampleBar,
+    this.isBadgeExample = false,
+  });
+
+  final void Function(int)? onSelectItem;
+  final int selectedIndex;
+  final bool isExampleBar;
+  final bool isBadgeExample;
+
+  @override
+  State<NavigationBars> createState() => _NavigationBarsState();
+}
+
+class _NavigationBarsState extends State<NavigationBars> {
+  late int selectedIndex;
+
+  @override
+  void initState() {
+    super.initState();
+    selectedIndex = widget.selectedIndex;
+  }
+
+  @override
+  void didUpdateWidget(covariant NavigationBars oldWidget) {
+    super.didUpdateWidget(oldWidget);
+    if (widget.selectedIndex != oldWidget.selectedIndex) {
+      selectedIndex = widget.selectedIndex;
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    // App NavigationBar should get first focus.
+    Widget navigationBar = Focus(
+      autofocus: !(widget.isExampleBar || widget.isBadgeExample),
+      child: NavigationBar(
+        selectedIndex: selectedIndex,
+        onDestinationSelected: (index) {
+          setState(() {
+            selectedIndex = index;
+          });
+          if (!widget.isExampleBar) widget.onSelectItem!(index);
+        },
+        destinations: widget.isExampleBar && widget.isBadgeExample
+            ? barWithBadgeDestinations
+            : widget.isExampleBar
+                ? exampleBarDestinations
+                : appBarDestinations,
+      ),
+    );
+
+    if (widget.isExampleBar && widget.isBadgeExample) {
+      navigationBar = ComponentDecoration(
+          label: 'Badges',
+          tooltipMessage: 'Use Badge or Badge.count',
+          child: navigationBar);
+    } else if (widget.isExampleBar) {
+      navigationBar = ComponentDecoration(
+          label: 'Navigation bar',
+          tooltipMessage: 'Use NavigationBar',
+          child: navigationBar);
+    }
+
+    return navigationBar;
+  }
+}
+
+class IconToggleButtons extends StatefulWidget {
+  const IconToggleButtons({super.key});
+
+  @override
+  State<IconToggleButtons> createState() => _IconToggleButtonsState();
+}
+
+class _IconToggleButtonsState extends State<IconToggleButtons> {
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Icon buttons',
+      tooltipMessage: 'Use IconButton',
+      child: Row(
+        mainAxisAlignment: MainAxisAlignment.spaceAround,
+        children: <Widget>[
+          Column(
+            // Standard IconButton
+            children: const <Widget>[
+              IconToggleButton(
+                isEnabled: true,
+                tooltip: 'Standard',
+              ),
+              colDivider,
+              IconToggleButton(
+                isEnabled: false,
+                tooltip: 'Standard (disabled)',
+              ),
+            ],
+          ),
+          Column(
+            children: const <Widget>[
+              // Filled IconButton
+              IconToggleButton(
+                isEnabled: true,
+                tooltip: 'Filled',
+                getDefaultStyle: enabledFilledButtonStyle,
+              ),
+              colDivider,
+              IconToggleButton(
+                isEnabled: false,
+                tooltip: 'Filled (disabled)',
+                getDefaultStyle: disabledFilledButtonStyle,
+              ),
+            ],
+          ),
+          Column(
+            children: const <Widget>[
+              // Filled Tonal IconButton
+              IconToggleButton(
+                isEnabled: true,
+                tooltip: 'Filled tonal',
+                getDefaultStyle: enabledFilledTonalButtonStyle,
+              ),
+              colDivider,
+              IconToggleButton(
+                isEnabled: false,
+                tooltip: 'Filled tonal (disabled)',
+                getDefaultStyle: disabledFilledTonalButtonStyle,
+              ),
+            ],
+          ),
+          Column(
+            children: const <Widget>[
+              // Outlined IconButton
+              IconToggleButton(
+                isEnabled: true,
+                tooltip: 'Outlined',
+                getDefaultStyle: enabledOutlinedButtonStyle,
+              ),
+              colDivider,
+              IconToggleButton(
+                isEnabled: false,
+                tooltip: 'Outlined (disabled)',
+                getDefaultStyle: disabledOutlinedButtonStyle,
+              ),
+            ],
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+class IconToggleButton extends StatefulWidget {
+  const IconToggleButton({
+    required this.isEnabled,
+    required this.tooltip,
+    this.getDefaultStyle,
+    super.key,
+  });
+
+  final bool isEnabled;
+  final String tooltip;
+  final ButtonStyle? Function(bool, ColorScheme)? getDefaultStyle;
+
+  @override
+  State<IconToggleButton> createState() => _IconToggleButtonState();
+}
+
+class _IconToggleButtonState extends State<IconToggleButton> {
+  bool selected = false;
+
+  @override
+  Widget build(BuildContext context) {
+    final ColorScheme colors = Theme.of(context).colorScheme;
+    final VoidCallback? onPressed = widget.isEnabled
+        ? () {
+            setState(() {
+              selected = !selected;
+            });
+          }
+        : null;
+    ButtonStyle? style = widget.getDefaultStyle?.call(selected, colors);
+
+    return IconButton(
+      visualDensity: VisualDensity.standard,
+      isSelected: selected,
+      tooltip: widget.tooltip,
+      icon: const Icon(Icons.settings_outlined),
+      selectedIcon: const Icon(Icons.settings),
+      onPressed: onPressed,
+      style: style,
+    );
+  }
+}
+
+ButtonStyle enabledFilledButtonStyle(bool selected, ColorScheme colors) {
+  return IconButton.styleFrom(
+    foregroundColor: selected ? colors.onPrimary : colors.primary,
+    backgroundColor: selected ? colors.primary : colors.surfaceVariant,
+    disabledForegroundColor: colors.onSurface.withOpacity(0.38),
+    disabledBackgroundColor: colors.onSurface.withOpacity(0.12),
+    hoverColor: selected
+        ? colors.onPrimary.withOpacity(0.08)
+        : colors.primary.withOpacity(0.08),
+    focusColor: selected
+        ? colors.onPrimary.withOpacity(0.12)
+        : colors.primary.withOpacity(0.12),
+    highlightColor: selected
+        ? colors.onPrimary.withOpacity(0.12)
+        : colors.primary.withOpacity(0.12),
+  );
+}
+
+ButtonStyle disabledFilledButtonStyle(bool selected, ColorScheme colors) {
+  return IconButton.styleFrom(
+    disabledForegroundColor: colors.onSurface.withOpacity(0.38),
+    disabledBackgroundColor: colors.onSurface.withOpacity(0.12),
+  );
+}
+
+ButtonStyle enabledFilledTonalButtonStyle(bool selected, ColorScheme colors) {
+  return IconButton.styleFrom(
+    foregroundColor:
+        selected ? colors.onSecondaryContainer : colors.onSurfaceVariant,
+    backgroundColor:
+        selected ? colors.secondaryContainer : colors.surfaceVariant,
+    hoverColor: selected
+        ? colors.onSecondaryContainer.withOpacity(0.08)
+        : colors.onSurfaceVariant.withOpacity(0.08),
+    focusColor: selected
+        ? colors.onSecondaryContainer.withOpacity(0.12)
+        : colors.onSurfaceVariant.withOpacity(0.12),
+    highlightColor: selected
+        ? colors.onSecondaryContainer.withOpacity(0.12)
+        : colors.onSurfaceVariant.withOpacity(0.12),
+  );
+}
+
+ButtonStyle disabledFilledTonalButtonStyle(bool selected, ColorScheme colors) {
+  return IconButton.styleFrom(
+    disabledForegroundColor: colors.onSurface.withOpacity(0.38),
+    disabledBackgroundColor: colors.onSurface.withOpacity(0.12),
+  );
+}
+
+ButtonStyle enabledOutlinedButtonStyle(bool selected, ColorScheme colors) {
+  return IconButton.styleFrom(
+    backgroundColor: selected ? colors.inverseSurface : null,
+    hoverColor: selected
+        ? colors.onInverseSurface.withOpacity(0.08)
+        : colors.onSurfaceVariant.withOpacity(0.08),
+    focusColor: selected
+        ? colors.onInverseSurface.withOpacity(0.12)
+        : colors.onSurfaceVariant.withOpacity(0.12),
+    highlightColor: selected
+        ? colors.onInverseSurface.withOpacity(0.12)
+        : colors.onSurface.withOpacity(0.12),
+    side: BorderSide(color: colors.outline),
+  ).copyWith(
+    foregroundColor: MaterialStateProperty.resolveWith((states) {
+      if (states.contains(MaterialState.selected)) {
+        return colors.onInverseSurface;
+      }
+      if (states.contains(MaterialState.pressed)) {
+        return colors.onSurface;
+      }
+      return null;
+    }),
+  );
+}
+
+ButtonStyle disabledOutlinedButtonStyle(bool selected, ColorScheme colors) {
+  return IconButton.styleFrom(
+    disabledForegroundColor: colors.onSurface.withOpacity(0.38),
+    disabledBackgroundColor:
+        selected ? colors.onSurface.withOpacity(0.12) : null,
+    side: selected ? null : BorderSide(color: colors.outline.withOpacity(0.12)),
+  );
+}
+
+class Chips extends StatefulWidget {
+  const Chips({super.key});
+
+  @override
+  State<Chips> createState() => _ChipsState();
+}
+
+class _ChipsState extends State<Chips> {
+  bool isFiltered = true;
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Chips',
+      tooltipMessage:
+          'Use ActionChip, FilterChip, or InputChip. \nActionChip can also be used for suggestion chip',
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.center,
+        children: <Widget>[
+          Wrap(
+            spacing: smallSpacing,
+            runSpacing: smallSpacing,
+            children: <Widget>[
+              ActionChip(
+                label: const Text('Assist'),
+                avatar: const Icon(Icons.event),
+                onPressed: () {},
+              ),
+              FilterChip(
+                label: const Text('Filter'),
+                selected: isFiltered,
+                onSelected: (selected) {
+                  setState(() => isFiltered = selected);
+                },
+              ),
+              InputChip(
+                label: const Text('Input'),
+                onPressed: () {},
+                onDeleted: () {},
+              ),
+              ActionChip(
+                label: const Text('Suggestion'),
+                onPressed: () {},
+              ),
+            ],
+          ),
+          colDivider,
+          Wrap(
+            spacing: smallSpacing,
+            runSpacing: smallSpacing,
+            children: <Widget>[
+              const ActionChip(
+                label: Text('Assist'),
+                avatar: Icon(Icons.event),
+              ),
+              FilterChip(
+                label: const Text('Filter'),
+                selected: isFiltered,
+                onSelected: null,
+              ),
+              InputChip(
+                label: const Text('Input'),
+                onDeleted: () {},
+                isEnabled: false,
+              ),
+              const ActionChip(
+                label: Text('Suggestion'),
+              ),
+            ],
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+class SegmentedButtons extends StatelessWidget {
+  const SegmentedButtons({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Segmented buttons',
+      tooltipMessage: 'Use SegmentedButton<T>',
+      child: Column(
+        children: const <Widget>[
+          SingleChoice(),
+          colDivider,
+          MultipleChoice(),
+        ],
+      ),
+    );
+  }
+}
+
+enum Calendar { day, week, month, year }
+
+class SingleChoice extends StatefulWidget {
+  const SingleChoice({super.key});
+
+  @override
+  State<SingleChoice> createState() => _SingleChoiceState();
+}
+
+class _SingleChoiceState extends State<SingleChoice> {
+  Calendar calendarView = Calendar.day;
+
+  @override
+  Widget build(BuildContext context) {
+    return SegmentedButton<Calendar>(
+      segments: const <ButtonSegment<Calendar>>[
+        ButtonSegment<Calendar>(
+            value: Calendar.day,
+            label: Text('Day'),
+            icon: Icon(Icons.calendar_view_day)),
+        ButtonSegment<Calendar>(
+            value: Calendar.week,
+            label: Text('Week'),
+            icon: Icon(Icons.calendar_view_week)),
+        ButtonSegment<Calendar>(
+            value: Calendar.month,
+            label: Text('Month'),
+            icon: Icon(Icons.calendar_view_month)),
+        ButtonSegment<Calendar>(
+            value: Calendar.year,
+            label: Text('Year'),
+            icon: Icon(Icons.calendar_today)),
+      ],
+      selected: <Calendar>{calendarView},
+      onSelectionChanged: (newSelection) {
+        setState(() {
+          // By default there is only a single segment that can be
+          // selected at one time, so its value is always the first
+          // item in the selected set.
+          calendarView = newSelection.first;
+        });
+      },
+    );
+  }
+}
+
+enum Sizes { extraSmall, small, medium, large, extraLarge }
+
+class MultipleChoice extends StatefulWidget {
+  const MultipleChoice({super.key});
+
+  @override
+  State<MultipleChoice> createState() => _MultipleChoiceState();
+}
+
+class _MultipleChoiceState extends State<MultipleChoice> {
+  Set<Sizes> selection = <Sizes>{Sizes.large, Sizes.extraLarge};
+
+  @override
+  Widget build(BuildContext context) {
+    return SegmentedButton<Sizes>(
+      segments: const <ButtonSegment<Sizes>>[
+        ButtonSegment<Sizes>(value: Sizes.extraSmall, label: Text('XS')),
+        ButtonSegment<Sizes>(value: Sizes.small, label: Text('S')),
+        ButtonSegment<Sizes>(value: Sizes.medium, label: Text('M')),
+        ButtonSegment<Sizes>(
+          value: Sizes.large,
+          label: Text('L'),
+        ),
+        ButtonSegment<Sizes>(value: Sizes.extraLarge, label: Text('XL')),
+      ],
+      selected: selection,
+      onSelectionChanged: (newSelection) {
+        setState(() {
+          selection = newSelection;
+        });
+      },
+      multiSelectionEnabled: true,
+    );
+  }
+}
+
+class SnackBarSection extends StatelessWidget {
+  const SnackBarSection({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Snackbar',
+      tooltipMessage:
+          'Use ScaffoldMessenger.of(context).showSnackBar with SnackBar',
+      child: TextButton(
+        onPressed: () {
+          final snackBar = SnackBar(
+            behavior: SnackBarBehavior.floating,
+            width: 400.0,
+            content: const Text('This is a snackbar'),
+            action: SnackBarAction(
+              label: 'Close',
+              onPressed: () {},
+            ),
+          );
+
+          ScaffoldMessenger.of(context).hideCurrentSnackBar();
+          ScaffoldMessenger.of(context).showSnackBar(snackBar);
+        },
+        child: const Text(
+          'Show snackbar',
+          style: TextStyle(fontWeight: FontWeight.bold),
+        ),
+      ),
+    );
+  }
+}
+
+class BottomSheetSection extends StatefulWidget {
+  const BottomSheetSection({super.key});
+
+  @override
+  State<BottomSheetSection> createState() => _BottomSheetSectionState();
+}
+
+class _BottomSheetSectionState extends State<BottomSheetSection> {
+  bool isNonModalBottomSheetOpen = false;
+  PersistentBottomSheetController<void>? _nonModalBottomSheetController;
+
+  @override
+  Widget build(BuildContext context) {
+    List<Widget> buttonList = <Widget>[
+      IconButton(onPressed: () {}, icon: const Icon(Icons.share_outlined)),
+      IconButton(onPressed: () {}, icon: const Icon(Icons.add)),
+      IconButton(onPressed: () {}, icon: const Icon(Icons.delete_outline)),
+      IconButton(onPressed: () {}, icon: const Icon(Icons.archive_outlined)),
+      IconButton(onPressed: () {}, icon: const Icon(Icons.settings_outlined)),
+      IconButton(onPressed: () {}, icon: const Icon(Icons.favorite_border)),
+    ];
+    List<Text> labelList = const <Text>[
+      Text('Share'),
+      Text('Add to'),
+      Text('Trash'),
+      Text('Archive'),
+      Text('Settings'),
+      Text('Favorite')
+    ];
+
+    buttonList = List.generate(
+        buttonList.length,
+        (index) => Padding(
+              padding: const EdgeInsets.fromLTRB(20.0, 30.0, 20.0, 20.0),
+              child: Column(
+                mainAxisAlignment: MainAxisAlignment.start,
+                children: [
+                  buttonList[index],
+                  labelList[index],
+                ],
+              ),
+            ));
+
+    return ComponentDecoration(
+      label: 'Bottom sheet',
+      tooltipMessage: 'Use showModalBottomSheet<T> or showBottomSheet<T>',
+      child: Wrap(
+        alignment: WrapAlignment.spaceEvenly,
+        children: [
+          TextButton(
+            child: const Text(
+              'Show modal bottom sheet',
+              style: TextStyle(fontWeight: FontWeight.bold),
+            ),
+            onPressed: () {
+              showModalBottomSheet<void>(
+                context: context,
+                // TODO: Remove when this is in the framework https://github.com/flutter/flutter/issues/118619
+                constraints: const BoxConstraints(maxWidth: 640),
+                builder: (context) {
+                  return SizedBox(
+                    height: 150,
+                    child: Padding(
+                      padding: const EdgeInsets.symmetric(horizontal: 32.0),
+                      child: ListView(
+                        shrinkWrap: true,
+                        scrollDirection: Axis.horizontal,
+                        children: buttonList,
+                      ),
+                    ),
+                  );
+                },
+              );
+            },
+          ),
+          TextButton(
+            child: Text(
+              isNonModalBottomSheetOpen
+                  ? 'Hide bottom sheet'
+                  : 'Show bottom sheet',
+              style: const TextStyle(fontWeight: FontWeight.bold),
+            ),
+            onPressed: () {
+              if (isNonModalBottomSheetOpen) {
+                _nonModalBottomSheetController?.close();
+                setState(() {
+                  isNonModalBottomSheetOpen = false;
+                });
+                return;
+              } else {
+                setState(() {
+                  isNonModalBottomSheetOpen = true;
+                });
+              }
+
+              _nonModalBottomSheetController = showBottomSheet<void>(
+                elevation: 8.0,
+                context: context,
+                // TODO: Remove when this is in the framework https://github.com/flutter/flutter/issues/118619
+                constraints: const BoxConstraints(maxWidth: 640),
+                builder: (context) {
+                  return SizedBox(
+                    height: 150,
+                    child: Padding(
+                      padding: const EdgeInsets.symmetric(horizontal: 32.0),
+                      child: ListView(
+                        shrinkWrap: true,
+                        scrollDirection: Axis.horizontal,
+                        children: buttonList,
+                      ),
+                    ),
+                  );
+                },
+              );
+            },
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+class BottomAppBars extends StatelessWidget {
+  const BottomAppBars({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Bottom app bar',
+      tooltipMessage: 'Use BottomAppBar',
+      child: Column(
+        children: [
+          SizedBox(
+            height: 80,
+            child: Scaffold(
+              floatingActionButton: FloatingActionButton(
+                onPressed: () {},
+                elevation: 0.0,
+                child: const Icon(Icons.add),
+              ),
+              floatingActionButtonLocation:
+                  FloatingActionButtonLocation.endContained,
+              bottomNavigationBar: BottomAppBar(
+                child: Row(
+                  children: <Widget>[
+                    const IconButtonAnchorExample(),
+                    IconButton(
+                      tooltip: 'Search',
+                      icon: const Icon(Icons.search),
+                      onPressed: () {},
+                    ),
+                    IconButton(
+                      tooltip: 'Favorite',
+                      icon: const Icon(Icons.favorite),
+                      onPressed: () {},
+                    ),
+                  ],
+                ),
+              ),
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+class IconButtonAnchorExample extends StatelessWidget {
+  const IconButtonAnchorExample({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return MenuAnchor(
+      builder: (context, controller, child) {
+        return IconButton(
+          onPressed: () {
+            if (controller.isOpen) {
+              controller.close();
+            } else {
+              controller.open();
+            }
+          },
+          icon: const Icon(Icons.more_vert),
+        );
+      },
+      menuChildren: [
+        MenuItemButton(
+          child: const Text('Menu 1'),
+          onPressed: () {},
+        ),
+        MenuItemButton(
+          child: const Text('Menu 2'),
+          onPressed: () {},
+        ),
+        SubmenuButton(
+          menuChildren: <Widget>[
+            MenuItemButton(
+              onPressed: () {},
+              child: const Text('Menu 3.1'),
+            ),
+            MenuItemButton(
+              onPressed: () {},
+              child: const Text('Menu 3.2'),
+            ),
+            MenuItemButton(
+              onPressed: () {},
+              child: const Text('Menu 3.3'),
+            ),
+          ],
+          child: const Text('Menu 3'),
+        ),
+      ],
+    );
+  }
+}
+
+class ButtonAnchorExample extends StatelessWidget {
+  const ButtonAnchorExample({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return MenuAnchor(
+      builder: (context, controller, child) {
+        return FilledButton.tonal(
+          onPressed: () {
+            if (controller.isOpen) {
+              controller.close();
+            } else {
+              controller.open();
+            }
+          },
+          child: const Text('Show menu'),
+        );
+      },
+      menuChildren: [
+        MenuItemButton(
+          leadingIcon: const Icon(Icons.people_alt_outlined),
+          child: const Text('Item 1'),
+          onPressed: () {},
+        ),
+        MenuItemButton(
+          leadingIcon: const Icon(Icons.remove_red_eye_outlined),
+          child: const Text('Item 2'),
+          onPressed: () {},
+        ),
+        MenuItemButton(
+          leadingIcon: const Icon(Icons.refresh),
+          onPressed: () {},
+          child: const Text('Item 3'),
+        ),
+      ],
+    );
+  }
+}
+
+class NavigationDrawers extends StatelessWidget {
+  const NavigationDrawers({super.key, required this.scaffoldKey});
+  final GlobalKey<ScaffoldState> scaffoldKey;
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Navigation drawer',
+      tooltipMessage:
+          'Use NavigationDrawer. For modal navigation drawers, see Scaffold.endDrawer',
+      child: Column(
+        children: [
+          const SizedBox(height: 520, child: NavigationDrawerSection()),
+          colDivider,
+          colDivider,
+          TextButton(
+            child: const Text('Show modal navigation drawer',
+                style: TextStyle(fontWeight: FontWeight.bold)),
+            onPressed: () {
+              scaffoldKey.currentState!.openEndDrawer();
+            },
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+class NavigationDrawerSection extends StatefulWidget {
+  const NavigationDrawerSection({super.key});
+
+  @override
+  State<NavigationDrawerSection> createState() =>
+      _NavigationDrawerSectionState();
+}
+
+class _NavigationDrawerSectionState extends State<NavigationDrawerSection> {
+  int navDrawerIndex = 0;
+
+  @override
+  Widget build(BuildContext context) {
+    return NavigationDrawer(
+      onDestinationSelected: (selectedIndex) {
+        setState(() {
+          navDrawerIndex = selectedIndex;
+        });
+      },
+      selectedIndex: navDrawerIndex,
+      children: <Widget>[
+        Padding(
+          padding: const EdgeInsets.fromLTRB(28, 16, 16, 10),
+          child: Text(
+            'Mail',
+            style: Theme.of(context).textTheme.titleSmall,
+          ),
+        ),
+        ...destinations.map((destination) {
+          return NavigationDrawerDestination(
+            label: Text(destination.label),
+            icon: destination.icon,
+            selectedIcon: destination.selectedIcon,
+          );
+        }),
+        const Divider(indent: 28, endIndent: 28),
+        Padding(
+          padding: const EdgeInsets.fromLTRB(28, 16, 16, 10),
+          child: Text(
+            'Labels',
+            style: Theme.of(context).textTheme.titleSmall,
+          ),
+        ),
+        ...labelDestinations.map((destination) {
+          return NavigationDrawerDestination(
+            label: Text(destination.label),
+            icon: destination.icon,
+            selectedIcon: destination.selectedIcon,
+          );
+        }),
+      ],
+    );
+  }
+}
+
+class ExampleDestination {
+  const ExampleDestination(this.label, this.icon, this.selectedIcon);
+
+  final String label;
+  final Widget icon;
+  final Widget selectedIcon;
+}
+
+const List<ExampleDestination> destinations = <ExampleDestination>[
+  ExampleDestination('Inbox', Icon(Icons.inbox_outlined), Icon(Icons.inbox)),
+  ExampleDestination('Outbox', Icon(Icons.send_outlined), Icon(Icons.send)),
+  ExampleDestination(
+      'Favorites', Icon(Icons.favorite_outline), Icon(Icons.favorite)),
+  ExampleDestination('Trash', Icon(Icons.delete_outline), Icon(Icons.delete)),
+];
+
+const List<ExampleDestination> labelDestinations = <ExampleDestination>[
+  ExampleDestination(
+      'Family', Icon(Icons.bookmark_border), Icon(Icons.bookmark)),
+  ExampleDestination(
+      'School', Icon(Icons.bookmark_border), Icon(Icons.bookmark)),
+  ExampleDestination('Work', Icon(Icons.bookmark_border), Icon(Icons.bookmark)),
+];
+
+class NavigationRails extends StatelessWidget {
+  const NavigationRails({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return const ComponentDecoration(
+      label: 'Navigation rail',
+      tooltipMessage: 'Use NavigationRail',
+      child: IntrinsicWidth(
+          child: SizedBox(height: 420, child: NavigationRailSection())),
+    );
+  }
+}
+
+class NavigationRailSection extends StatefulWidget {
+  const NavigationRailSection({super.key});
+
+  @override
+  State<NavigationRailSection> createState() => _NavigationRailSectionState();
+}
+
+class _NavigationRailSectionState extends State<NavigationRailSection> {
+  int navRailIndex = 0;
+
+  @override
+  Widget build(BuildContext context) {
+    return NavigationRail(
+      onDestinationSelected: (selectedIndex) {
+        setState(() {
+          navRailIndex = selectedIndex;
+        });
+      },
+      elevation: 4,
+      leading: FloatingActionButton(
+          child: const Icon(Icons.create), onPressed: () {}),
+      groupAlignment: 0.0,
+      selectedIndex: navRailIndex,
+      labelType: NavigationRailLabelType.selected,
+      destinations: <NavigationRailDestination>[
+        ...destinations.map((destination) {
+          return NavigationRailDestination(
+            label: Text(destination.label),
+            icon: destination.icon,
+            selectedIcon: destination.selectedIcon,
+          );
+        }),
+      ],
+    );
+  }
+}
+
+class Tabs extends StatefulWidget {
+  const Tabs({super.key});
+
+  @override
+  State<Tabs> createState() => _TabsState();
+}
+
+class _TabsState extends State<Tabs> with TickerProviderStateMixin {
+  late TabController _tabController;
+
+  @override
+  void initState() {
+    super.initState();
+    _tabController = TabController(length: 3, vsync: this);
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Tabs',
+      tooltipMessage: 'Use TabBar',
+      child: SizedBox(
+        height: 80,
+        child: Scaffold(
+          appBar: AppBar(
+            bottom: TabBar(
+              controller: _tabController,
+              tabs: const <Widget>[
+                Tab(
+                  icon: Icon(Icons.videocam_outlined),
+                  text: 'Video',
+                  iconMargin: EdgeInsets.only(bottom: 0.0),
+                ),
+                Tab(
+                  icon: Icon(Icons.photo_outlined),
+                  text: 'Photos',
+                  iconMargin: EdgeInsets.only(bottom: 0.0),
+                ),
+                Tab(
+                  icon: Icon(Icons.audiotrack_sharp),
+                  text: 'Audio',
+                  iconMargin: EdgeInsets.only(bottom: 0.0),
+                ),
+              ],
+            ),
+            // TODO: Showcase secondary tab bar https://github.com/flutter/flutter/issues/111962
+          ),
+        ),
+      ),
+    );
+  }
+}
+
+class TopAppBars extends StatelessWidget {
+  const TopAppBars({super.key});
+
+  static final actions = [
+    IconButton(icon: const Icon(Icons.attach_file), onPressed: () {}),
+    IconButton(icon: const Icon(Icons.event), onPressed: () {}),
+    IconButton(icon: const Icon(Icons.more_vert), onPressed: () {}),
+  ];
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+      label: 'Top app bars',
+      tooltipMessage:
+          'Use AppBar, SliverAppBar, SliverAppBar.medium, or  SliverAppBar.large',
+      child: Column(
+        children: [
+          AppBar(
+            title: const Text('Center-aligned'),
+            leading: const BackButton(),
+            actions: [
+              IconButton(
+                iconSize: 32,
+                icon: const Icon(Icons.account_circle_outlined),
+                onPressed: () {},
+              ),
+            ],
+            centerTitle: true,
+          ),
+          colDivider,
+          AppBar(
+            title: const Text('Small'),
+            leading: const BackButton(),
+            actions: actions,
+            centerTitle: false,
+          ),
+          colDivider,
+          SizedBox(
+            height: 100,
+            child: CustomScrollView(
+              slivers: [
+                SliverAppBar.medium(
+                  title: const Text('Medium'),
+                  leading: const BackButton(),
+                  actions: actions,
+                ),
+                const SliverFillRemaining(),
+              ],
+            ),
+          ),
+          colDivider,
+          SizedBox(
+            height: 130,
+            child: CustomScrollView(
+              slivers: [
+                SliverAppBar.large(
+                  title: const Text('Large'),
+                  leading: const BackButton(),
+                  actions: actions,
+                ),
+                const SliverFillRemaining(),
+              ],
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+class Menus extends StatefulWidget {
+  const Menus({super.key});
+
+  @override
+  State<Menus> createState() => _MenusState();
+}
+
+class _MenusState extends State<Menus> {
+  final TextEditingController colorController = TextEditingController();
+  final TextEditingController iconController = TextEditingController();
+  IconLabel? selectedIcon = IconLabel.smile;
+  ColorLabel? selectedColor;
+
+  @override
+  Widget build(BuildContext context) {
+    final List<DropdownMenuEntry<ColorLabel>> colorEntries =
+        <DropdownMenuEntry<ColorLabel>>[];
+    for (final ColorLabel color in ColorLabel.values) {
+      colorEntries.add(DropdownMenuEntry<ColorLabel>(
+          value: color, label: color.label, enabled: color.label != 'Grey'));
+    }
+
+    final List<DropdownMenuEntry<IconLabel>> iconEntries =
+        <DropdownMenuEntry<IconLabel>>[];
+    for (final IconLabel icon in IconLabel.values) {
+      iconEntries
+          .add(DropdownMenuEntry<IconLabel>(value: icon, label: icon.label));
+    }
+
+    return ComponentDecoration(
+      label: 'Menus',
+      tooltipMessage: 'Use MenuAnchor or DropdownMenu<T>',
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.center,
+            children: const <Widget>[
+              ButtonAnchorExample(),
+              rowDivider,
+              IconButtonAnchorExample(),
+            ],
+          ),
+          colDivider,
+          Wrap(
+            alignment: WrapAlignment.spaceAround,
+            runAlignment: WrapAlignment.center,
+            crossAxisAlignment: WrapCrossAlignment.center,
+            spacing: smallSpacing,
+            runSpacing: smallSpacing,
+            children: [
+              DropdownMenu<ColorLabel>(
+                controller: colorController,
+                label: const Text('Color'),
+                enableFilter: true,
+                dropdownMenuEntries: colorEntries,
+                inputDecorationTheme: const InputDecorationTheme(filled: true),
+                onSelected: (color) {
+                  setState(() {
+                    selectedColor = color;
+                  });
+                },
+              ),
+              DropdownMenu<IconLabel>(
+                initialSelection: IconLabel.smile,
+                controller: iconController,
+                leadingIcon: const Icon(Icons.search),
+                label: const Text('Icon'),
+                dropdownMenuEntries: iconEntries,
+                onSelected: (icon) {
+                  setState(() {
+                    selectedIcon = icon;
+                  });
+                },
+              ),
+              Icon(
+                selectedIcon?.icon,
+                color: selectedColor?.color ?? Colors.grey.withOpacity(0.5),
+              )
+            ],
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+enum ColorLabel {
+  blue('Blue', Colors.blue),
+  pink('Pink', Colors.pink),
+  green('Green', Colors.green),
+  yellow('Yellow', Colors.yellow),
+  grey('Grey', Colors.grey);
+
+  const ColorLabel(this.label, this.color);
+  final String label;
+  final Color color;
+}
+
+enum IconLabel {
+  smile('Smile', Icons.sentiment_satisfied_outlined),
+  cloud(
+    'Cloud',
+    Icons.cloud_outlined,
+  ),
+  brush('Brush', Icons.brush_outlined),
+  heart('Heart', Icons.favorite);
+
+  const IconLabel(this.label, this.icon);
+  final String label;
+  final IconData icon;
+}
+
+class Sliders extends StatefulWidget {
+  const Sliders({super.key});
+
+  @override
+  State<Sliders> createState() => _SlidersState();
+}
+
+class _SlidersState extends State<Sliders> {
+  double sliderValue0 = 30.0;
+  double sliderValue1 = 20.0;
+
+  @override
+  Widget build(BuildContext context) {
+    return ComponentDecoration(
+        label: 'Sliders',
+        tooltipMessage: 'Use Slider or RangeSlider',
+        child: Column(
+          children: <Widget>[
+            Slider(
+              max: 100,
+              value: sliderValue0,
+              onChanged: (value) {
+                setState(() {
+                  sliderValue0 = value;
+                });
+              },
+            ),
+            const SizedBox(height: 20),
+            Slider(
+              max: 100,
+              divisions: 5,
+              value: sliderValue1,
+              label: sliderValue1.round().toString(),
+              onChanged: (value) {
+                setState(() {
+                  sliderValue1 = value;
+                });
+              },
+            ),
+          ],
+        ));
+  }
+}
+
+class ComponentDecoration extends StatefulWidget {
+  const ComponentDecoration({
+    super.key,
+    required this.label,
+    required this.child,
+    this.tooltipMessage = '',
+  });
+
+  final String label;
+  final Widget child;
+  final String? tooltipMessage;
+
+  @override
+  State<ComponentDecoration> createState() => _ComponentDecorationState();
+}
+
+class _ComponentDecorationState extends State<ComponentDecoration> {
+  final focusNode = FocusNode();
+
+  @override
+  Widget build(BuildContext context) {
+    return RepaintBoundary(
+      child: Padding(
+        padding: const EdgeInsets.symmetric(vertical: smallSpacing),
+        child: Column(
+          children: [
+            Row(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: [
+                Text(widget.label,
+                    style: Theme.of(context).textTheme.titleSmall),
+                Tooltip(
+                  message: widget.tooltipMessage,
+                  child: const Padding(
+                      padding: EdgeInsets.symmetric(horizontal: 5.0),
+                      child: Icon(Icons.info_outline, size: 16)),
+                ),
+              ],
+            ),
+            ConstrainedBox(
+              constraints:
+                  const BoxConstraints.tightFor(width: widthConstraint),
+              // Tapping within the a component card should request focus
+              // for that component's children.
+              child: Focus(
+                focusNode: focusNode,
+                canRequestFocus: true,
+                child: GestureDetector(
+                  onTapDown: (_) {
+                    focusNode.requestFocus();
+                  },
+                  behavior: HitTestBehavior.opaque,
+                  child: Card(
+                    elevation: 0,
+                    shape: RoundedRectangleBorder(
+                      side: BorderSide(
+                        color: Theme.of(context).colorScheme.outlineVariant,
+                      ),
+                      borderRadius: const BorderRadius.all(Radius.circular(12)),
+                    ),
+                    child: Padding(
+                      padding: const EdgeInsets.symmetric(
+                          horizontal: 5.0, vertical: 20.0),
+                      child: Center(
+                        child: widget.child,
+                      ),
+                    ),
+                  ),
+                ),
+              ),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+class ComponentGroupDecoration extends StatelessWidget {
+  const ComponentGroupDecoration(
+      {super.key, required this.label, required this.children});
+
+  final String label;
+  final List<Widget> children;
+
+  @override
+  Widget build(BuildContext context) {
+    // Fully traverse this component group before moving on
+    return FocusTraversalGroup(
+      child: Card(
+        margin: EdgeInsets.zero,
+        elevation: 0,
+        color: Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.3),
+        child: Padding(
+          padding: const EdgeInsets.symmetric(vertical: 20.0),
+          child: Center(
+            child: Column(
+              children: [
+                Text(label, style: Theme.of(context).textTheme.titleLarge),
+                colDivider,
+                ...children
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+}

+ 40 - 0
lib/constants.dart

@@ -0,0 +1,40 @@
+// Copyright 2021 The Flutter team. 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/material.dart';
+
+// NavigationRail shows if the screen width is greater or equal to
+// narrowScreenWidthThreshold; otherwise, NavigationBar is used for navigation.
+const double narrowScreenWidthThreshold = 450;
+
+const double mediumWidthBreakpoint = 1000;
+const double largeWidthBreakpoint = 1500;
+
+const double transitionLength = 500;
+
+enum ColorSeed {
+  baseColor('M3 Baseline', Color(0xff6750a4)),
+  indigo('Indigo', Colors.indigo),
+  blue('Blue', Colors.blue),
+  teal('Teal', Colors.teal),
+  green('Green', Colors.green),
+  yellow('Yellow', Colors.yellow),
+  orange('Orange', Colors.orange),
+  deepOrange('Deep Orange', Colors.deepOrange),
+  pink('Pink', Colors.pink);
+
+  const ColorSeed(this.label, this.color);
+  final String label;
+  final Color color;
+}
+
+enum ScreenSelected {
+  component(0),
+  color(1),
+  typography(2),
+  elevation(3);
+
+  const ScreenSelected(this.value);
+  final int value;
+}

+ 184 - 0
lib/elevation_screen.dart

@@ -0,0 +1,184 @@
+// Copyright 2021 The Flutter team. 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/material.dart';
+
+class ElevationScreen extends StatelessWidget {
+  const ElevationScreen({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    Color shadowColor = Theme.of(context).colorScheme.shadow;
+    Color surfaceTint = Theme.of(context).colorScheme.primary;
+    return Expanded(
+      child: CustomScrollView(
+        slivers: [
+          SliverToBoxAdapter(
+            child: Padding(
+              padding: const EdgeInsets.fromLTRB(16.0, 20, 16.0, 0),
+              child: Text(
+                'Surface Tint Color Only',
+                style: Theme.of(context).textTheme.titleLarge,
+              ),
+            ),
+          ),
+          ElevationGrid(surfaceTintColor: surfaceTint),
+          SliverList(
+            delegate: SliverChildListDelegate(<Widget>[
+              const SizedBox(height: 10),
+              Padding(
+                padding: const EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 0),
+                child: Text(
+                  'Surface Tint Color and Shadow Color',
+                  style: Theme.of(context).textTheme.titleLarge,
+                ),
+              ),
+            ]),
+          ),
+          ElevationGrid(
+            shadowColor: shadowColor,
+            surfaceTintColor: surfaceTint,
+          ),
+          SliverList(
+            delegate: SliverChildListDelegate(<Widget>[
+              const SizedBox(height: 10),
+              Padding(
+                padding: const EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 0),
+                child: Text(
+                  'Shadow Color Only',
+                  style: Theme.of(context).textTheme.titleLarge,
+                ),
+              ),
+            ]),
+          ),
+          ElevationGrid(shadowColor: shadowColor),
+        ],
+      ),
+    );
+  }
+}
+
+const double narrowScreenWidthThreshold = 450;
+
+class ElevationGrid extends StatelessWidget {
+  const ElevationGrid({super.key, this.shadowColor, this.surfaceTintColor});
+
+  final Color? shadowColor;
+  final Color? surfaceTintColor;
+
+  List<ElevationCard> elevationCards(
+      Color? shadowColor, Color? surfaceTintColor) {
+    return elevations
+        .map(
+          (elevationInfo) => ElevationCard(
+            info: elevationInfo,
+            shadowColor: shadowColor,
+            surfaceTint: surfaceTintColor,
+          ),
+        )
+        .toList();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return SliverPadding(
+      padding: const EdgeInsets.all(8),
+      sliver: SliverLayoutBuilder(builder: (context, constraints) {
+        if (constraints.crossAxisExtent < narrowScreenWidthThreshold) {
+          return SliverGrid.count(
+            crossAxisCount: 3,
+            children: elevationCards(shadowColor, surfaceTintColor),
+          );
+        } else {
+          return SliverGrid.count(
+            crossAxisCount: 6,
+            children: elevationCards(shadowColor, surfaceTintColor),
+          );
+        }
+      }),
+    );
+  }
+}
+
+class ElevationCard extends StatefulWidget {
+  const ElevationCard(
+      {super.key, required this.info, this.shadowColor, this.surfaceTint});
+
+  final ElevationInfo info;
+  final Color? shadowColor;
+  final Color? surfaceTint;
+
+  @override
+  State<ElevationCard> createState() => _ElevationCardState();
+}
+
+class _ElevationCardState extends State<ElevationCard> {
+  late double _elevation;
+
+  @override
+  void initState() {
+    super.initState();
+    _elevation = widget.info.elevation;
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    const BorderRadius borderRadius = BorderRadius.all(Radius.circular(4.0));
+    final Color color = Theme.of(context).colorScheme.surface;
+
+    return Padding(
+      padding: const EdgeInsets.all(8.0),
+      child: Material(
+        borderRadius: borderRadius,
+        elevation: _elevation,
+        color: color,
+        shadowColor: widget.shadowColor,
+        surfaceTintColor: widget.surfaceTint,
+        type: MaterialType.card,
+        child: Padding(
+          padding: const EdgeInsets.all(8.0),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: <Widget>[
+              Text(
+                'Level ${widget.info.level}',
+                style: Theme.of(context).textTheme.labelMedium,
+              ),
+              Text(
+                '${widget.info.level.toInt()} dp',
+                style: Theme.of(context).textTheme.labelMedium,
+              ),
+              if (widget.surfaceTint != null)
+                Expanded(
+                  child: Align(
+                    alignment: Alignment.bottomRight,
+                    child: Text(
+                      '${widget.info.overlayPercent}%',
+                      style: Theme.of(context).textTheme.bodySmall,
+                    ),
+                  ),
+                ),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+}
+
+class ElevationInfo {
+  const ElevationInfo(this.level, this.elevation, this.overlayPercent);
+  final int level;
+  final double elevation;
+  final int overlayPercent;
+}
+
+const List<ElevationInfo> elevations = <ElevationInfo>[
+  ElevationInfo(0, 0.0, 0),
+  ElevationInfo(1, 1.0, 5),
+  ElevationInfo(2, 3.0, 8),
+  ElevationInfo(3, 6.0, 11),
+  ElevationInfo(4, 8.0, 12),
+  ElevationInfo(5, 12.0, 14),
+];

+ 665 - 0
lib/home.dart

@@ -0,0 +1,665 @@
+// Copyright 2021 The Flutter team. 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/material.dart';
+
+import 'color_palettes_screen.dart';
+import 'component_screen.dart';
+import 'constants.dart';
+import 'elevation_screen.dart';
+import 'typography_screen.dart';
+
+class Home extends StatefulWidget {
+  const Home({
+    super.key,
+    required this.useLightMode,
+    required this.useMaterial3,
+    required this.colorSelected,
+    required this.handleBrightnessChange,
+    required this.handleMaterialVersionChange,
+    required this.handleColorSelect,
+  });
+
+  final bool useLightMode;
+  final bool useMaterial3;
+  final ColorSeed colorSelected;
+  final void Function(bool useLightMode) handleBrightnessChange;
+  final void Function() handleMaterialVersionChange;
+  final void Function(int value) handleColorSelect;
+
+  @override
+  State<Home> createState() => _HomeState();
+}
+
+class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
+  final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
+  late final AnimationController controller;
+  late final CurvedAnimation railAnimation;
+  bool controllerInitialized = false;
+  bool showMediumSizeLayout = false;
+  bool showLargeSizeLayout = false;
+
+  int screenIndex = ScreenSelected.component.value;
+
+  @override
+  initState() {
+    super.initState();
+    controller = AnimationController(
+      duration: Duration(milliseconds: transitionLength.toInt() * 2),
+      value: 0,
+      vsync: this,
+    );
+    railAnimation = CurvedAnimation(
+      parent: controller,
+      curve: const Interval(0.5, 1.0),
+    );
+  }
+
+  @override
+  void dispose() {
+    controller.dispose();
+    super.dispose();
+  }
+
+  @override
+  void didChangeDependencies() {
+    super.didChangeDependencies();
+
+    final double width = MediaQuery.of(context).size.width;
+    final AnimationStatus status = controller.status;
+    if (width > mediumWidthBreakpoint) {
+      if (width > largeWidthBreakpoint) {
+        showMediumSizeLayout = false;
+        showLargeSizeLayout = true;
+      } else {
+        showMediumSizeLayout = true;
+        showLargeSizeLayout = false;
+      }
+      if (status != AnimationStatus.forward &&
+          status != AnimationStatus.completed) {
+        controller.forward();
+      }
+    } else {
+      showMediumSizeLayout = false;
+      showLargeSizeLayout = false;
+      if (status != AnimationStatus.reverse &&
+          status != AnimationStatus.dismissed) {
+        controller.reverse();
+      }
+    }
+    if (!controllerInitialized) {
+      controllerInitialized = true;
+      controller.value = width > mediumWidthBreakpoint ? 1 : 0;
+    }
+  }
+
+  void handleScreenChanged(int screenSelected) {
+    setState(() {
+      screenIndex = screenSelected;
+    });
+  }
+
+  Widget createScreenFor(
+      ScreenSelected screenSelected, bool showNavBarExample) {
+    switch (screenSelected) {
+      case ScreenSelected.component:
+        return Expanded(
+          child: OneTwoTransition(
+            animation: railAnimation,
+            one: FirstComponentList(
+                showNavBottomBar: showNavBarExample,
+                scaffoldKey: scaffoldKey,
+                showSecondList: showMediumSizeLayout || showLargeSizeLayout),
+            two: SecondComponentList(
+              scaffoldKey: scaffoldKey,
+            ),
+          ),
+        );
+      case ScreenSelected.color:
+        return const ColorPalettesScreen();
+      case ScreenSelected.typography:
+        return const TypographyScreen();
+      case ScreenSelected.elevation:
+        return const ElevationScreen();
+      default:
+        return FirstComponentList(
+            showNavBottomBar: showNavBarExample,
+            scaffoldKey: scaffoldKey,
+            showSecondList: showMediumSizeLayout || showLargeSizeLayout);
+    }
+  }
+
+  PreferredSizeWidget createAppBar() {
+    return AppBar(
+      title: widget.useMaterial3
+          ? const Text('Material 3')
+          : const Text('Material 2'),
+      actions: !showMediumSizeLayout && !showLargeSizeLayout
+          ? [
+              _BrightnessButton(
+                handleBrightnessChange: widget.handleBrightnessChange,
+              ),
+              _Material3Button(
+                handleMaterialVersionChange: widget.handleMaterialVersionChange,
+              ),
+              _ColorSeedButton(
+                handleColorSelect: widget.handleColorSelect,
+                colorSelected: widget.colorSelected,
+              ),
+            ]
+          : [Container()],
+    );
+  }
+
+  Widget _expandedTrailingActions() => Container(
+        constraints: const BoxConstraints.tightFor(width: 250),
+        padding: const EdgeInsets.symmetric(horizontal: 30),
+        child: Column(
+          mainAxisAlignment: MainAxisAlignment.end,
+          crossAxisAlignment: CrossAxisAlignment.stretch,
+          children: [
+            Row(
+              children: [
+                const Text('Brightness'),
+                Expanded(child: Container()),
+                Switch(
+                    value: widget.useLightMode,
+                    onChanged: (value) {
+                      widget.handleBrightnessChange(value);
+                    })
+              ],
+            ),
+            Row(
+              children: [
+                widget.useMaterial3
+                    ? const Text('Material 3')
+                    : const Text('Material 2'),
+                Expanded(child: Container()),
+                Switch(
+                    value: widget.useMaterial3,
+                    onChanged: (_) {
+                      widget.handleMaterialVersionChange();
+                    })
+              ],
+            ),
+            const Divider(),
+            ConstrainedBox(
+              constraints: const BoxConstraints(maxHeight: 200.0),
+              child: GridView.count(
+                crossAxisCount: 3,
+                children: List.generate(
+                    ColorSeed.values.length,
+                    (i) => IconButton(
+                          icon: const Icon(Icons.radio_button_unchecked),
+                          color: ColorSeed.values[i].color,
+                          isSelected: widget.colorSelected.color ==
+                              ColorSeed.values[i].color,
+                          selectedIcon: const Icon(Icons.circle),
+                          onPressed: () {
+                            widget.handleColorSelect(i);
+                          },
+                        )),
+              ),
+            ),
+          ],
+        ),
+      );
+
+  Widget _trailingActions() => Column(
+        mainAxisAlignment: MainAxisAlignment.end,
+        children: [
+          Flexible(
+            child: _BrightnessButton(
+              handleBrightnessChange: widget.handleBrightnessChange,
+              showTooltipBelow: false,
+            ),
+          ),
+          Flexible(
+            child: _Material3Button(
+              handleMaterialVersionChange: widget.handleMaterialVersionChange,
+              showTooltipBelow: false,
+            ),
+          ),
+          Flexible(
+            child: _ColorSeedButton(
+              handleColorSelect: widget.handleColorSelect,
+              colorSelected: widget.colorSelected,
+            ),
+          ),
+        ],
+      );
+
+  @override
+  Widget build(BuildContext context) {
+    return AnimatedBuilder(
+      animation: controller,
+      builder: (context, child) {
+        return NavigationTransition(
+          scaffoldKey: scaffoldKey,
+          animationController: controller,
+          railAnimation: railAnimation,
+          appBar: createAppBar(),
+          body: createScreenFor(
+              ScreenSelected.values[screenIndex], controller.value == 1),
+          navigationRail: NavigationRail(
+            extended: showLargeSizeLayout,
+            destinations: navRailDestinations,
+            selectedIndex: screenIndex,
+            onDestinationSelected: (index) {
+              setState(() {
+                screenIndex = index;
+                handleScreenChanged(screenIndex);
+              });
+            },
+            trailing: Expanded(
+              child: Padding(
+                padding: const EdgeInsets.only(bottom: 20),
+                child: showLargeSizeLayout
+                    ? _expandedTrailingActions()
+                    : _trailingActions(),
+              ),
+            ),
+          ),
+          navigationBar: NavigationBars(
+            onSelectItem: (index) {
+              setState(() {
+                screenIndex = index;
+                handleScreenChanged(screenIndex);
+              });
+            },
+            selectedIndex: screenIndex,
+            isExampleBar: false,
+          ),
+        );
+      },
+    );
+  }
+}
+
+class _BrightnessButton extends StatelessWidget {
+  const _BrightnessButton({
+    required this.handleBrightnessChange,
+    this.showTooltipBelow = true,
+  });
+
+  final Function handleBrightnessChange;
+  final bool showTooltipBelow;
+
+  @override
+  Widget build(BuildContext context) {
+    final isBright = Theme.of(context).brightness == Brightness.light;
+    return Tooltip(
+      preferBelow: showTooltipBelow,
+      message: 'Toggle brightness',
+      child: IconButton(
+        icon: isBright
+            ? const Icon(Icons.dark_mode_outlined)
+            : const Icon(Icons.light_mode_outlined),
+        onPressed: () => handleBrightnessChange(!isBright),
+      ),
+    );
+  }
+}
+
+class _Material3Button extends StatelessWidget {
+  const _Material3Button({
+    required this.handleMaterialVersionChange,
+    this.showTooltipBelow = true,
+  });
+
+  final void Function() handleMaterialVersionChange;
+  final bool showTooltipBelow;
+
+  @override
+  Widget build(BuildContext context) {
+    final useMaterial3 = Theme.of(context).useMaterial3;
+    return Tooltip(
+      preferBelow: showTooltipBelow,
+      message: 'Switch to Material ${useMaterial3 ? 2 : 3}',
+      child: IconButton(
+        icon: useMaterial3
+            ? const Icon(Icons.filter_2)
+            : const Icon(Icons.filter_3),
+        onPressed: handleMaterialVersionChange,
+      ),
+    );
+  }
+}
+
+class _ColorSeedButton extends StatelessWidget {
+  const _ColorSeedButton({
+    required this.handleColorSelect,
+    required this.colorSelected,
+  });
+
+  final void Function(int) handleColorSelect;
+  final ColorSeed colorSelected;
+
+  @override
+  Widget build(BuildContext context) {
+    return PopupMenuButton(
+      icon: Icon(
+        Icons.palette_outlined,
+        color: Theme.of(context).colorScheme.onSurfaceVariant,
+      ),
+      tooltip: 'Select a seed color',
+      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
+      itemBuilder: (context) {
+        return List.generate(ColorSeed.values.length, (index) {
+          ColorSeed currentColor = ColorSeed.values[index];
+
+          return PopupMenuItem(
+            value: index,
+            enabled: currentColor != colorSelected,
+            child: Wrap(
+              children: [
+                Padding(
+                  padding: const EdgeInsets.only(left: 10),
+                  child: Icon(
+                    currentColor == colorSelected
+                        ? Icons.color_lens
+                        : Icons.color_lens_outlined,
+                    color: currentColor.color,
+                  ),
+                ),
+                Padding(
+                  padding: const EdgeInsets.only(left: 20),
+                  child: Text(currentColor.label),
+                ),
+              ],
+            ),
+          );
+        });
+      },
+      onSelected: handleColorSelect,
+    );
+  }
+}
+
+class NavigationTransition extends StatefulWidget {
+  const NavigationTransition(
+      {super.key,
+      required this.scaffoldKey,
+      required this.animationController,
+      required this.railAnimation,
+      required this.navigationRail,
+      required this.navigationBar,
+      required this.appBar,
+      required this.body});
+
+  final GlobalKey<ScaffoldState> scaffoldKey;
+  final AnimationController animationController;
+  final CurvedAnimation railAnimation;
+  final Widget navigationRail;
+  final Widget navigationBar;
+  final PreferredSizeWidget appBar;
+  final Widget body;
+
+  @override
+  State<NavigationTransition> createState() => _NavigationTransitionState();
+}
+
+class _NavigationTransitionState extends State<NavigationTransition> {
+  late final AnimationController controller;
+  late final CurvedAnimation railAnimation;
+  late final ReverseAnimation barAnimation;
+  bool controllerInitialized = false;
+  bool showDivider = false;
+
+  @override
+  void initState() {
+    super.initState();
+
+    controller = widget.animationController;
+    railAnimation = widget.railAnimation;
+
+    barAnimation = ReverseAnimation(
+      CurvedAnimation(
+        parent: controller,
+        curve: const Interval(0.0, 0.5),
+      ),
+    );
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final ColorScheme colorScheme = Theme.of(context).colorScheme;
+
+    return Scaffold(
+      key: widget.scaffoldKey,
+      appBar: widget.appBar,
+      body: Row(
+        children: <Widget>[
+          RailTransition(
+            animation: railAnimation,
+            backgroundColor: colorScheme.surface,
+            child: widget.navigationRail,
+          ),
+          widget.body,
+        ],
+      ),
+      bottomNavigationBar: BarTransition(
+        animation: barAnimation,
+        backgroundColor: colorScheme.surface,
+        child: widget.navigationBar,
+      ),
+      endDrawer: const NavigationDrawerSection(),
+    );
+  }
+}
+
+final List<NavigationRailDestination> navRailDestinations = appBarDestinations
+    .map(
+      (destination) => NavigationRailDestination(
+        icon: Tooltip(
+          message: destination.label,
+          child: destination.icon,
+        ),
+        selectedIcon: Tooltip(
+          message: destination.label,
+          child: destination.selectedIcon,
+        ),
+        label: Text(destination.label),
+      ),
+    )
+    .toList();
+
+class SizeAnimation extends CurvedAnimation {
+  SizeAnimation(Animation<double> parent)
+      : super(
+          parent: parent,
+          curve: const Interval(
+            0.2,
+            0.8,
+            curve: Curves.easeInOutCubicEmphasized,
+          ),
+          reverseCurve: Interval(
+            0,
+            0.2,
+            curve: Curves.easeInOutCubicEmphasized.flipped,
+          ),
+        );
+}
+
+class OffsetAnimation extends CurvedAnimation {
+  OffsetAnimation(Animation<double> parent)
+      : super(
+          parent: parent,
+          curve: const Interval(
+            0.4,
+            1.0,
+            curve: Curves.easeInOutCubicEmphasized,
+          ),
+          reverseCurve: Interval(
+            0,
+            0.2,
+            curve: Curves.easeInOutCubicEmphasized.flipped,
+          ),
+        );
+}
+
+class RailTransition extends StatefulWidget {
+  const RailTransition(
+      {super.key,
+      required this.animation,
+      required this.backgroundColor,
+      required this.child});
+
+  final Animation<double> animation;
+  final Widget child;
+  final Color backgroundColor;
+
+  @override
+  State<RailTransition> createState() => _RailTransition();
+}
+
+class _RailTransition extends State<RailTransition> {
+  late Animation<Offset> offsetAnimation;
+  late Animation<double> widthAnimation;
+
+  @override
+  void didChangeDependencies() {
+    super.didChangeDependencies();
+
+    // The animations are only rebuilt by this method when the text
+    // direction changes because this widget only depends on Directionality.
+    final bool ltr = Directionality.of(context) == TextDirection.ltr;
+
+    widthAnimation = Tween<double>(
+      begin: 0,
+      end: 1,
+    ).animate(SizeAnimation(widget.animation));
+
+    offsetAnimation = Tween<Offset>(
+      begin: ltr ? const Offset(-1, 0) : const Offset(1, 0),
+      end: Offset.zero,
+    ).animate(OffsetAnimation(widget.animation));
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return ClipRect(
+      child: DecoratedBox(
+        decoration: BoxDecoration(color: widget.backgroundColor),
+        child: Align(
+          alignment: Alignment.topLeft,
+          widthFactor: widthAnimation.value,
+          child: FractionalTranslation(
+            translation: offsetAnimation.value,
+            child: widget.child,
+          ),
+        ),
+      ),
+    );
+  }
+}
+
+class BarTransition extends StatefulWidget {
+  const BarTransition(
+      {super.key,
+      required this.animation,
+      required this.backgroundColor,
+      required this.child});
+
+  final Animation<double> animation;
+  final Color backgroundColor;
+  final Widget child;
+
+  @override
+  State<BarTransition> createState() => _BarTransition();
+}
+
+class _BarTransition extends State<BarTransition> {
+  late final Animation<Offset> offsetAnimation;
+  late final Animation<double> heightAnimation;
+
+  @override
+  void initState() {
+    super.initState();
+
+    offsetAnimation = Tween<Offset>(
+      begin: const Offset(0, 1),
+      end: Offset.zero,
+    ).animate(OffsetAnimation(widget.animation));
+
+    heightAnimation = Tween<double>(
+      begin: 0,
+      end: 1,
+    ).animate(SizeAnimation(widget.animation));
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return ClipRect(
+      child: DecoratedBox(
+        decoration: BoxDecoration(color: widget.backgroundColor),
+        child: Align(
+          alignment: Alignment.topLeft,
+          heightFactor: heightAnimation.value,
+          child: FractionalTranslation(
+            translation: offsetAnimation.value,
+            child: widget.child,
+          ),
+        ),
+      ),
+    );
+  }
+}
+
+class OneTwoTransition extends StatefulWidget {
+  const OneTwoTransition({
+    super.key,
+    required this.animation,
+    required this.one,
+    required this.two,
+  });
+
+  final Animation<double> animation;
+  final Widget one;
+  final Widget two;
+
+  @override
+  State<OneTwoTransition> createState() => _OneTwoTransitionState();
+}
+
+class _OneTwoTransitionState extends State<OneTwoTransition> {
+  late final Animation<Offset> offsetAnimation;
+  late final Animation<double> widthAnimation;
+
+  @override
+  void initState() {
+    super.initState();
+
+    offsetAnimation = Tween<Offset>(
+      begin: const Offset(1, 0),
+      end: Offset.zero,
+    ).animate(OffsetAnimation(widget.animation));
+
+    widthAnimation = Tween<double>(
+      begin: 0,
+      end: mediumWidthBreakpoint,
+    ).animate(SizeAnimation(widget.animation));
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Row(
+      children: <Widget>[
+        Flexible(
+          flex: mediumWidthBreakpoint.toInt(),
+          child: widget.one,
+        ),
+        if (widthAnimation.value.toInt() > 0) ...[
+          Flexible(
+            flex: widthAnimation.value.toInt(),
+            child: FractionalTranslation(
+              translation: offsetAnimation.value,
+              child: widget.two,
+            ),
+          )
+        ],
+      ],
+    );
+  }
+}

+ 35 - 0
lib/main.dart

@@ -0,0 +1,35 @@
+// Copyright 2021 The Flutter team. 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/material.dart';
+
+import 'myself/my_home.dart';
+
+void main() {
+  runApp(
+    const App(),
+  );
+}
+
+class App extends StatefulWidget {
+  const App({super.key});
+
+  @override
+  _AppState createState() => _AppState();
+}
+
+class _AppState extends State<App> {
+  @override
+  Widget build(BuildContext context) {
+    return MaterialApp(
+      title: 'Flutter  Demo',
+      theme: ThemeData(
+        primarySwatch: Colors.blue
+      ),
+      home: MyHomePage(title: 'MyHomePage'),
+    );
+  }
+}
+
+

+ 85 - 0
lib/main_bak.dart

@@ -0,0 +1,85 @@
+// Copyright 2021 The Flutter team. 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/material.dart';
+import 'package:flutter/scheduler.dart';
+
+import 'constants.dart';
+import 'home.dart';
+
+void main() {
+  runApp(
+    const App(),
+  );
+}
+
+class App extends StatefulWidget {
+  const App({super.key});
+
+  @override
+  State<App> createState() => _AppState();
+}
+
+class _AppState extends State<App> {
+  bool useMaterial3 = true;
+  ThemeMode themeMode = ThemeMode.system;
+  ColorSeed colorSelected = ColorSeed.baseColor;
+
+  bool get useLightMode {
+    switch (themeMode) {
+      case ThemeMode.system:
+        return SchedulerBinding.instance.window.platformBrightness ==
+            Brightness.light;
+      case ThemeMode.light:
+        return true;
+      case ThemeMode.dark:
+        return false;
+    }
+  }
+
+  void handleBrightnessChange(bool useLightMode) {
+    setState(() {
+      themeMode = useLightMode ? ThemeMode.light : ThemeMode.dark;
+    });
+  }
+
+  void handleMaterialVersionChange() {
+    setState(() {
+      useMaterial3 = !useMaterial3;
+    });
+  }
+
+  void handleColorSelect(int value) {
+    setState(() {
+      colorSelected = ColorSeed.values[value];
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return MaterialApp(
+      debugShowCheckedModeBanner: false,
+      title: 'Material 3',
+      themeMode: themeMode,
+      theme: ThemeData(
+        colorSchemeSeed: colorSelected.color,
+        useMaterial3: useMaterial3,
+        brightness: Brightness.light,
+      ),
+      darkTheme: ThemeData(
+        colorSchemeSeed: colorSelected.color,
+        useMaterial3: useMaterial3,
+        brightness: Brightness.dark,
+      ),
+      home: Home(
+        useLightMode: useLightMode,
+        useMaterial3: useMaterial3,
+        colorSelected: colorSelected,
+        handleBrightnessChange: handleBrightnessChange,
+        handleMaterialVersionChange: handleMaterialVersionChange,
+        handleColorSelect: handleColorSelect,
+      ),
+    );
+  }
+}

+ 33 - 0
lib/myself/my_home.dart

@@ -0,0 +1,33 @@
+import 'package:flutter/material.dart';
+
+class MyHomePage extends StatefulWidget {
+  final String title;
+  const MyHomePage({Key? key, required this.title}): super(key: key);
+
+  @override
+  _MyHomeState createState() => _MyHomeState();
+}
+
+class _MyHomeState extends State<MyHomePage> {
+  int _counter = 0;
+
+  void _incrementCounter() {
+    setState(() {
+      _counter++;
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    // TODO: implement build
+    return Scaffold(
+      appBar: AppBar(title: Text(widget.title)),
+      body: Text('$_counter'),
+      floatingActionButton: FloatingActionButton(
+          onPressed: _incrementCounter, 
+          tooltip: 'Increment',
+          child: Icon(Icons.add),
+        ),
+    );
+  }
+}

+ 63 - 0
lib/typography_screen.dart

@@ -0,0 +1,63 @@
+// Copyright 2021 The Flutter team. 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/material.dart';
+
+class TypographyScreen extends StatelessWidget {
+  const TypographyScreen({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    final textTheme = Theme.of(context)
+        .textTheme
+        .apply(displayColor: Theme.of(context).colorScheme.onSurface);
+    return Expanded(
+      child: ListView(
+        children: <Widget>[
+          const SizedBox(height: 7),
+          TextStyleExample(
+              name: 'Display Large', style: textTheme.displayLarge!),
+          TextStyleExample(
+              name: 'Display Medium', style: textTheme.displayMedium!),
+          TextStyleExample(
+              name: 'Display Small', style: textTheme.displaySmall!),
+          TextStyleExample(
+              name: 'Headline Large', style: textTheme.headlineLarge!),
+          TextStyleExample(
+              name: 'Headline Medium', style: textTheme.headlineMedium!),
+          TextStyleExample(
+              name: 'Headline Small', style: textTheme.headlineSmall!),
+          TextStyleExample(name: 'Title Large', style: textTheme.titleLarge!),
+          TextStyleExample(name: 'Title Medium', style: textTheme.titleMedium!),
+          TextStyleExample(name: 'Title Small', style: textTheme.titleSmall!),
+          TextStyleExample(name: 'Label Large', style: textTheme.labelLarge!),
+          TextStyleExample(name: 'Label Medium', style: textTheme.labelMedium!),
+          TextStyleExample(name: 'Label Small', style: textTheme.labelSmall!),
+          TextStyleExample(name: 'Body Large', style: textTheme.bodyLarge!),
+          TextStyleExample(name: 'Body Medium', style: textTheme.bodyMedium!),
+          TextStyleExample(name: 'Body Small', style: textTheme.bodySmall!),
+        ],
+      ),
+    );
+  }
+}
+
+class TextStyleExample extends StatelessWidget {
+  const TextStyleExample({
+    super.key,
+    required this.name,
+    required this.style,
+  });
+
+  final String name;
+  final TextStyle style;
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: const EdgeInsets.all(8.0),
+      child: Text(name, style: style),
+    );
+  }
+}

+ 7 - 0
macos/.gitignore

@@ -0,0 +1,7 @@
+# Flutter-related
+**/Flutter/ephemeral/
+**/Pods/
+
+# Xcode-related
+**/dgph
+**/xcuserdata/

+ 2 - 0
macos/Flutter/Flutter-Debug.xcconfig

@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
+#include "ephemeral/Flutter-Generated.xcconfig"

+ 2 - 0
macos/Flutter/Flutter-Release.xcconfig

@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
+#include "ephemeral/Flutter-Generated.xcconfig"

+ 12 - 0
macos/Flutter/GeneratedPluginRegistrant.swift

@@ -0,0 +1,12 @@
+//
+//  Generated file. Do not edit.
+//
+
+import FlutterMacOS
+import Foundation
+
+import url_launcher_macos
+
+func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
+  UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
+}

+ 43 - 0
macos/Podfile

@@ -0,0 +1,43 @@
+platform :osx, '10.14'
+
+# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
+ENV['COCOAPODS_DISABLE_STATS'] = 'true'
+
+project 'Runner', {
+  'Debug' => :debug,
+  'Profile' => :release,
+  'Release' => :release,
+}
+
+def flutter_root
+  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
+  unless File.exist?(generated_xcode_build_settings_path)
+    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
+  end
+
+  File.foreach(generated_xcode_build_settings_path) do |line|
+    matches = line.match(/FLUTTER_ROOT\=(.*)/)
+    return matches[1].strip if matches
+  end
+  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
+end
+
+require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
+
+flutter_macos_podfile_setup
+
+target 'Runner' do
+  use_frameworks!
+  use_modular_headers!
+
+  flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
+  target 'RunnerTests' do
+    inherit! :search_paths
+  end
+end
+
+post_install do |installer|
+  installer.pods_project.targets.each do |target|
+    flutter_additional_macos_build_settings(target)
+  end
+end

+ 791 - 0
macos/Runner.xcodeproj/project.pbxproj

@@ -0,0 +1,791 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 54;
+	objects = {
+
+/* Begin PBXAggregateTarget section */
+		33CC111A2044C6BA0003C045 /* Flutter Assemble */ = {
+			isa = PBXAggregateTarget;
+			buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */;
+			buildPhases = (
+				33CC111E2044C6BF0003C045 /* ShellScript */,
+			);
+			dependencies = (
+			);
+			name = "Flutter Assemble";
+			productName = FLX;
+		};
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+		331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; };
+		335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
+		33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
+		33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
+		33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
+		33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
+		8A01491D4F8F4D00A21C70B1 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F83F0741DAD616014AF9AF /* Pods_RunnerTests.framework */; };
+		9089F01F734C0E2927D9257A /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 29A9C9BA0B172C7AF4BA0093 /* Pods_Runner.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 33CC10EC2044A3C60003C045;
+			remoteInfo = Runner;
+		};
+		33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 33CC111A2044C6BA0003C045;
+			remoteInfo = FLX;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		33CC110E2044A8840003C045 /* Bundle Framework */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "";
+			dstSubfolderSpec = 10;
+			files = (
+			);
+			name = "Bundle Framework";
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		29A9C9BA0B172C7AF4BA0093 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		2F60BF8A68193F3AEAB06C94 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
+		331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+		331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
+		333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
+		335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
+		33CC10ED2044A3C60003C045 /* material_3_demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = material_3_demo.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
+		33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
+		33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
+		33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = "<group>"; };
+		33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = "<group>"; };
+		33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = "<group>"; };
+		33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = "<group>"; };
+		33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = "<group>"; };
+		33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
+		33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
+		33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
+		38FFB7E33F3328A2324F8DA5 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
+		7968DABC1F868801DFCE878B /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
+		7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
+		9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
+		982A9546C7F4AC82B7E38331 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
+		BED67DC2CFEA837634438CBB /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
+		D55DD26CB4C48F1B83E2D777 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
+		F1F83F0741DAD616014AF9AF /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		331C80D2294CF70F00263BE5 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8A01491D4F8F4D00A21C70B1 /* Pods_RunnerTests.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		33CC10EA2044A3C60003C045 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				9089F01F734C0E2927D9257A /* Pods_Runner.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		331C80D6294CF71000263BE5 /* RunnerTests */ = {
+			isa = PBXGroup;
+			children = (
+				331C80D7294CF71000263BE5 /* RunnerTests.swift */,
+			);
+			path = RunnerTests;
+			sourceTree = "<group>";
+		};
+		33BA886A226E78AF003329D5 /* Configs */ = {
+			isa = PBXGroup;
+			children = (
+				33E5194F232828860026EE4D /* AppInfo.xcconfig */,
+				9740EEB21CF90195004384FC /* Debug.xcconfig */,
+				7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+				333000ED22D3DE5D00554162 /* Warnings.xcconfig */,
+			);
+			path = Configs;
+			sourceTree = "<group>";
+		};
+		33CC10E42044A3C60003C045 = {
+			isa = PBXGroup;
+			children = (
+				33FAB671232836740065AC1E /* Runner */,
+				33CEB47122A05771004F2AC0 /* Flutter */,
+				331C80D6294CF71000263BE5 /* RunnerTests */,
+				33CC10EE2044A3C60003C045 /* Products */,
+				D73912EC22F37F3D000D13A0 /* Frameworks */,
+				FECF7CD70D5F4ED3EC598F84 /* Pods */,
+			);
+			sourceTree = "<group>";
+		};
+		33CC10EE2044A3C60003C045 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				33CC10ED2044A3C60003C045 /* material_3_demo.app */,
+				331C80D5294CF71000263BE5 /* RunnerTests.xctest */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		33CC11242044D66E0003C045 /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				33CC10F22044A3C60003C045 /* Assets.xcassets */,
+				33CC10F42044A3C60003C045 /* MainMenu.xib */,
+				33CC10F72044A3C60003C045 /* Info.plist */,
+			);
+			name = Resources;
+			path = ..;
+			sourceTree = "<group>";
+		};
+		33CEB47122A05771004F2AC0 /* Flutter */ = {
+			isa = PBXGroup;
+			children = (
+				335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,
+				33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
+				33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
+				33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
+			);
+			path = Flutter;
+			sourceTree = "<group>";
+		};
+		33FAB671232836740065AC1E /* Runner */ = {
+			isa = PBXGroup;
+			children = (
+				33CC10F02044A3C60003C045 /* AppDelegate.swift */,
+				33CC11122044BFA00003C045 /* MainFlutterWindow.swift */,
+				33E51913231747F40026EE4D /* DebugProfile.entitlements */,
+				33E51914231749380026EE4D /* Release.entitlements */,
+				33CC11242044D66E0003C045 /* Resources */,
+				33BA886A226E78AF003329D5 /* Configs */,
+			);
+			path = Runner;
+			sourceTree = "<group>";
+		};
+		D73912EC22F37F3D000D13A0 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				29A9C9BA0B172C7AF4BA0093 /* Pods_Runner.framework */,
+				F1F83F0741DAD616014AF9AF /* Pods_RunnerTests.framework */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		FECF7CD70D5F4ED3EC598F84 /* Pods */ = {
+			isa = PBXGroup;
+			children = (
+				2F60BF8A68193F3AEAB06C94 /* Pods-Runner.debug.xcconfig */,
+				D55DD26CB4C48F1B83E2D777 /* Pods-Runner.release.xcconfig */,
+				7968DABC1F868801DFCE878B /* Pods-Runner.profile.xcconfig */,
+				BED67DC2CFEA837634438CBB /* Pods-RunnerTests.debug.xcconfig */,
+				38FFB7E33F3328A2324F8DA5 /* Pods-RunnerTests.release.xcconfig */,
+				982A9546C7F4AC82B7E38331 /* Pods-RunnerTests.profile.xcconfig */,
+			);
+			name = Pods;
+			path = Pods;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		331C80D4294CF70F00263BE5 /* RunnerTests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
+			buildPhases = (
+				B8E72633BEBC805AE03CD2B8 /* [CP] Check Pods Manifest.lock */,
+				331C80D1294CF70F00263BE5 /* Sources */,
+				331C80D2294CF70F00263BE5 /* Frameworks */,
+				331C80D3294CF70F00263BE5 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				331C80DA294CF71000263BE5 /* PBXTargetDependency */,
+			);
+			name = RunnerTests;
+			productName = RunnerTests;
+			productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */;
+			productType = "com.apple.product-type.bundle.unit-test";
+		};
+		33CC10EC2044A3C60003C045 /* Runner */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
+			buildPhases = (
+				AF1C2DFEDF8D1686770ABAAE /* [CP] Check Pods Manifest.lock */,
+				33CC10E92044A3C60003C045 /* Sources */,
+				33CC10EA2044A3C60003C045 /* Frameworks */,
+				33CC10EB2044A3C60003C045 /* Resources */,
+				33CC110E2044A8840003C045 /* Bundle Framework */,
+				3399D490228B24CF009A79C7 /* ShellScript */,
+				CFB41A6DFE042F35E1E6EA84 /* [CP] Embed Pods Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				33CC11202044C79F0003C045 /* PBXTargetDependency */,
+			);
+			name = Runner;
+			productName = Runner;
+			productReference = 33CC10ED2044A3C60003C045 /* material_3_demo.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		33CC10E52044A3C60003C045 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastSwiftUpdateCheck = 0920;
+				LastUpgradeCheck = 1300;
+				ORGANIZATIONNAME = "";
+				TargetAttributes = {
+					331C80D4294CF70F00263BE5 = {
+						CreatedOnToolsVersion = 14.0;
+						TestTargetID = 33CC10EC2044A3C60003C045;
+					};
+					33CC10EC2044A3C60003C045 = {
+						CreatedOnToolsVersion = 9.2;
+						LastSwiftMigration = 1100;
+						ProvisioningStyle = Automatic;
+						SystemCapabilities = {
+							com.apple.Sandbox = {
+								enabled = 1;
+							};
+						};
+					};
+					33CC111A2044C6BA0003C045 = {
+						CreatedOnToolsVersion = 9.2;
+						ProvisioningStyle = Manual;
+					};
+				};
+			};
+			buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */;
+			compatibilityVersion = "Xcode 9.3";
+			developmentRegion = en;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+				Base,
+			);
+			mainGroup = 33CC10E42044A3C60003C045;
+			productRefGroup = 33CC10EE2044A3C60003C045 /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				33CC10EC2044A3C60003C045 /* Runner */,
+				331C80D4294CF70F00263BE5 /* RunnerTests */,
+				33CC111A2044C6BA0003C045 /* Flutter Assemble */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		331C80D3294CF70F00263BE5 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		33CC10EB2044A3C60003C045 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
+				33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		3399D490228B24CF009A79C7 /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			alwaysOutOfDate = 1;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+			);
+			outputFileListPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
+		};
+		33CC111E2044C6BF0003C045 /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+				Flutter/ephemeral/FlutterInputs.xcfilelist,
+			);
+			inputPaths = (
+				Flutter/ephemeral/tripwire,
+			);
+			outputFileListPaths = (
+				Flutter/ephemeral/FlutterOutputs.xcfilelist,
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
+		};
+		AF1C2DFEDF8D1686770ABAAE /* [CP] Check Pods Manifest.lock */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
+			outputFileListPaths = (
+			);
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+			showEnvVarsInLog = 0;
+		};
+		B8E72633BEBC805AE03CD2B8 /* [CP] Check Pods Manifest.lock */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
+			outputFileListPaths = (
+			);
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+			showEnvVarsInLog = 0;
+		};
+		CFB41A6DFE042F35E1E6EA84 /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputFileListPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		331C80D1294CF70F00263BE5 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		33CC10E92044A3C60003C045 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */,
+				33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */,
+				335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		331C80DA294CF71000263BE5 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 33CC10EC2044A3C60003C045 /* Runner */;
+			targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */;
+		};
+		33CC11202044C79F0003C045 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */;
+			targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+		33CC10F42044A3C60003C045 /* MainMenu.xib */ = {
+			isa = PBXVariantGroup;
+			children = (
+				33CC10F52044A3C60003C045 /* Base */,
+			);
+			name = MainMenu.xib;
+			path = Runner;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		331C80DB294CF71000263BE5 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = BED67DC2CFEA837634438CBB /* Pods-RunnerTests.debug.xcconfig */;
+			buildSettings = {
+				BUNDLE_LOADER = "$(TEST_HOST)";
+				CURRENT_PROJECT_VERSION = 1;
+				GENERATE_INFOPLIST_FILE = YES;
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = com.example.material3Demo.RunnerTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_VERSION = 5.0;
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/material_3_demo.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/material_3_demo";
+			};
+			name = Debug;
+		};
+		331C80DC294CF71000263BE5 /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 38FFB7E33F3328A2324F8DA5 /* Pods-RunnerTests.release.xcconfig */;
+			buildSettings = {
+				BUNDLE_LOADER = "$(TEST_HOST)";
+				CURRENT_PROJECT_VERSION = 1;
+				GENERATE_INFOPLIST_FILE = YES;
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = com.example.material3Demo.RunnerTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_VERSION = 5.0;
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/material_3_demo.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/material_3_demo";
+			};
+			name = Release;
+		};
+		331C80DD294CF71000263BE5 /* Profile */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 982A9546C7F4AC82B7E38331 /* Pods-RunnerTests.profile.xcconfig */;
+			buildSettings = {
+				BUNDLE_LOADER = "$(TEST_HOST)";
+				CURRENT_PROJECT_VERSION = 1;
+				GENERATE_INFOPLIST_FILE = YES;
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = com.example.material3Demo.RunnerTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_VERSION = 5.0;
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/material_3_demo.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/material_3_demo";
+			};
+			name = Profile;
+		};
+		338D0CE9231458BD00FA5F75 /* Profile */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CODE_SIGN_IDENTITY = "-";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = macosx;
+				SWIFT_COMPILATION_MODE = wholemodule;
+				SWIFT_OPTIMIZATION_LEVEL = "-O";
+			};
+			name = Profile;
+		};
+		338D0CEA231458BD00FA5F75 /* Profile */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
+				CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
+				CODE_SIGN_STYLE = Automatic;
+				COMBINE_HIDPI_IMAGES = YES;
+				INFOPLIST_FILE = Runner/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/../Frameworks",
+				);
+				PROVISIONING_PROFILE_SPECIFIER = "";
+				SWIFT_VERSION = 5.0;
+			};
+			name = Profile;
+		};
+		338D0CEB231458BD00FA5F75 /* Profile */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_STYLE = Manual;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Profile;
+		};
+		33CC10F92044A3C60003C045 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CODE_SIGN_IDENTITY = "-";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
+				MTL_ENABLE_DEBUG_INFO = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = macosx;
+				SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+			};
+			name = Debug;
+		};
+		33CC10FA2044A3C60003C045 /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CODE_SIGN_IDENTITY = "-";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = macosx;
+				SWIFT_COMPILATION_MODE = wholemodule;
+				SWIFT_OPTIMIZATION_LEVEL = "-O";
+			};
+			name = Release;
+		};
+		33CC10FC2044A3C60003C045 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
+				CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
+				CODE_SIGN_STYLE = Automatic;
+				COMBINE_HIDPI_IMAGES = YES;
+				INFOPLIST_FILE = Runner/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/../Frameworks",
+				);
+				PROVISIONING_PROFILE_SPECIFIER = "";
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+				SWIFT_VERSION = 5.0;
+			};
+			name = Debug;
+		};
+		33CC10FD2044A3C60003C045 /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
+				CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
+				CODE_SIGN_STYLE = Automatic;
+				COMBINE_HIDPI_IMAGES = YES;
+				INFOPLIST_FILE = Runner/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/../Frameworks",
+				);
+				PROVISIONING_PROFILE_SPECIFIER = "";
+				SWIFT_VERSION = 5.0;
+			};
+			name = Release;
+		};
+		33CC111C2044C6BA0003C045 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_STYLE = Manual;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Debug;
+		};
+		33CC111D2044C6BA0003C045 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_STYLE = Automatic;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				331C80DB294CF71000263BE5 /* Debug */,
+				331C80DC294CF71000263BE5 /* Release */,
+				331C80DD294CF71000263BE5 /* Profile */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				33CC10F92044A3C60003C045 /* Debug */,
+				33CC10FA2044A3C60003C045 /* Release */,
+				338D0CE9231458BD00FA5F75 /* Profile */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				33CC10FC2044A3C60003C045 /* Debug */,
+				33CC10FD2044A3C60003C045 /* Release */,
+				338D0CEA231458BD00FA5F75 /* Profile */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				33CC111C2044C6BA0003C045 /* Debug */,
+				33CC111D2044C6BA0003C045 /* Release */,
+				338D0CEB231458BD00FA5F75 /* Profile */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 33CC10E52044A3C60003C045 /* Project object */;
+}

+ 8 - 0
macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IDEDidComputeMac32BitWarning</key>
+	<true/>
+</dict>
+</plist>

+ 98 - 0
macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme

@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1300"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "33CC10EC2044A3C60003C045"
+               BuildableName = "material_3_demo.app"
+               BlueprintName = "Runner"
+               ReferencedContainer = "container:Runner.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "33CC10EC2044A3C60003C045"
+            BuildableName = "material_3_demo.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+      <Testables>
+         <TestableReference
+             skipped = "NO"
+             parallelizable = "YES">
+             <BuildableReference
+                BuildableIdentifier = "primary"
+                BlueprintIdentifier = "331C80D4294CF70F00263BE5"
+                BuildableName = "RunnerTests.xctest"
+                BlueprintName = "RunnerTests"
+                ReferencedContainer = "container:Runner.xcodeproj">
+             </BuildableReference>
+          </TestableReference>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "33CC10EC2044A3C60003C045"
+            BuildableName = "material_3_demo.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Profile"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "33CC10EC2044A3C60003C045"
+            BuildableName = "material_3_demo.app"
+            BlueprintName = "Runner"
+            ReferencedContainer = "container:Runner.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

+ 10 - 0
macos/Runner.xcworkspace/contents.xcworkspacedata

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "group:Runner.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:Pods/Pods.xcodeproj">
+   </FileRef>
+</Workspace>

+ 8 - 0
macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IDEDidComputeMac32BitWarning</key>
+	<true/>
+</dict>
+</plist>

+ 9 - 0
macos/Runner/AppDelegate.swift

@@ -0,0 +1,9 @@
+import Cocoa
+import FlutterMacOS
+
+@NSApplicationMain
+class AppDelegate: FlutterAppDelegate {
+  override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
+    return true
+  }
+}

+ 68 - 0
macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json

@@ -0,0 +1,68 @@
+{
+  "images" : [
+    {
+      "size" : "16x16",
+      "idiom" : "mac",
+      "filename" : "app_icon_16.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "16x16",
+      "idiom" : "mac",
+      "filename" : "app_icon_32.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "32x32",
+      "idiom" : "mac",
+      "filename" : "app_icon_32.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "32x32",
+      "idiom" : "mac",
+      "filename" : "app_icon_64.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "128x128",
+      "idiom" : "mac",
+      "filename" : "app_icon_128.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "128x128",
+      "idiom" : "mac",
+      "filename" : "app_icon_256.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "256x256",
+      "idiom" : "mac",
+      "filename" : "app_icon_256.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "256x256",
+      "idiom" : "mac",
+      "filename" : "app_icon_512.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "512x512",
+      "idiom" : "mac",
+      "filename" : "app_icon_512.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "512x512",
+      "idiom" : "mac",
+      "filename" : "app_icon_1024.png",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

BIN
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png


BIN
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png


BIN
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png


BIN
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png


BIN
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png


BIN
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png


BIN
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png


+ 343 - 0
macos/Runner/Base.lproj/MainMenu.xib

@@ -0,0 +1,343 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
+            <connections>
+                <outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Runner" customModuleProvider="target">
+            <connections>
+                <outlet property="applicationMenu" destination="uQy-DD-JDr" id="XBo-yE-nKs"/>
+                <outlet property="mainFlutterWindow" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
+            </connections>
+        </customObject>
+        <customObject id="YLy-65-1bz" customClass="NSFontManager"/>
+        <menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
+            <items>
+                <menuItem title="APP_NAME" id="1Xt-HY-uBw">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                    <menu key="submenu" title="APP_NAME" systemMenu="apple" id="uQy-DD-JDr">
+                        <items>
+                            <menuItem title="About APP_NAME" id="5kV-Vb-QxS">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
+                            <menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
+                            <menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
+                            <menuItem title="Services" id="NMo-om-nkz">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
+                            <menuItem title="Hide APP_NAME" keyEquivalent="h" id="Olw-nP-bQN">
+                                <connections>
+                                    <action selector="hide:" target="-1" id="PnN-Uc-m68"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
+                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+                                <connections>
+                                    <action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Show All" id="Kd2-mp-pUS">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
+                            <menuItem title="Quit APP_NAME" keyEquivalent="q" id="4sb-4s-VLi">
+                                <connections>
+                                    <action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
+                                </connections>
+                            </menuItem>
+                        </items>
+                    </menu>
+                </menuItem>
+                <menuItem title="Edit" id="5QF-Oa-p0T">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                    <menu key="submenu" title="Edit" id="W48-6f-4Dl">
+                        <items>
+                            <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
+                                <connections>
+                                    <action selector="undo:" target="-1" id="M6e-cu-g7V"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
+                                <connections>
+                                    <action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
+                            <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
+                                <connections>
+                                    <action selector="cut:" target="-1" id="YJe-68-I9s"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
+                                <connections>
+                                    <action selector="copy:" target="-1" id="G1f-GL-Joy"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
+                                <connections>
+                                    <action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
+                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+                                <connections>
+                                    <action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Delete" id="pa3-QI-u2k">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
+                                <connections>
+                                    <action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
+                            <menuItem title="Find" id="4EN-yA-p0u">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <menu key="submenu" title="Find" id="1b7-l0-nxx">
+                                    <items>
+                                        <menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
+                                            <connections>
+                                                <action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
+                                            <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+                                            <connections>
+                                                <action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
+                                            <connections>
+                                                <action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
+                                            <connections>
+                                                <action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
+                                            <connections>
+                                                <action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
+                                            <connections>
+                                                <action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
+                                            </connections>
+                                        </menuItem>
+                                    </items>
+                                </menu>
+                            </menuItem>
+                            <menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
+                                    <items>
+                                        <menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
+                                            <connections>
+                                                <action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
+                                            <connections>
+                                                <action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
+                                        <menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
+                                            </connections>
+                                        </menuItem>
+                                    </items>
+                                </menu>
+                            </menuItem>
+                            <menuItem title="Substitutions" id="9ic-FL-obx">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
+                                    <items>
+                                        <menuItem title="Show Substitutions" id="z6F-FW-3nz">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
+                                        <menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Smart Quotes" id="hQb-2v-fYv">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Smart Dashes" id="rgM-f4-ycn">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Smart Links" id="cwL-P1-jid">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Data Detectors" id="tRr-pd-1PS">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Text Replacement" id="HFQ-gK-NFA">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
+                                            </connections>
+                                        </menuItem>
+                                    </items>
+                                </menu>
+                            </menuItem>
+                            <menuItem title="Transformations" id="2oI-Rn-ZJC">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <menu key="submenu" title="Transformations" id="c8a-y6-VQd">
+                                    <items>
+                                        <menuItem title="Make Upper Case" id="vmV-6d-7jI">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Make Lower Case" id="d9M-CD-aMd">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Capitalize" id="UEZ-Bs-lqG">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
+                                            </connections>
+                                        </menuItem>
+                                    </items>
+                                </menu>
+                            </menuItem>
+                            <menuItem title="Speech" id="xrE-MZ-jX0">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <menu key="submenu" title="Speech" id="3rS-ZA-NoH">
+                                    <items>
+                                        <menuItem title="Start Speaking" id="Ynk-f8-cLZ">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
+                                            </connections>
+                                        </menuItem>
+                                        <menuItem title="Stop Speaking" id="Oyz-dy-DGm">
+                                            <modifierMask key="keyEquivalentModifierMask"/>
+                                            <connections>
+                                                <action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
+                                            </connections>
+                                        </menuItem>
+                                    </items>
+                                </menu>
+                            </menuItem>
+                        </items>
+                    </menu>
+                </menuItem>
+                <menuItem title="View" id="H8h-7b-M4v">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                    <menu key="submenu" title="View" id="HyV-fh-RgO">
+                        <items>
+                            <menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
+                                <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+                                <connections>
+                                    <action selector="toggleFullScreen:" target="-1" id="dU3-MA-1Rq"/>
+                                </connections>
+                            </menuItem>
+                        </items>
+                    </menu>
+                </menuItem>
+                <menuItem title="Window" id="aUF-d1-5bR">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                    <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
+                        <items>
+                            <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
+                                <connections>
+                                    <action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Zoom" id="R4o-n2-Eq4">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
+                            <menuItem title="Bring All to Front" id="LE2-aR-0XJ">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
+                                </connections>
+                            </menuItem>
+                        </items>
+                    </menu>
+                </menuItem>
+                <menuItem title="Help" id="EPT-qC-fAb">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                    <menu key="submenu" title="Help" systemMenu="help" id="rJ0-wn-3NY"/>
+                </menuItem>
+            </items>
+            <point key="canvasLocation" x="142" y="-258"/>
+        </menu>
+        <window title="APP_NAME" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="MainFlutterWindow" customModule="Runner" customModuleProvider="target">
+            <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
+            <rect key="contentRect" x="335" y="390" width="800" height="600"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1577"/>
+            <view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
+                <rect key="frame" x="0.0" y="0.0" width="800" height="600"/>
+                <autoresizingMask key="autoresizingMask"/>
+            </view>
+        </window>
+    </objects>
+</document>

+ 14 - 0
macos/Runner/Configs/AppInfo.xcconfig

@@ -0,0 +1,14 @@
+// Application-level settings for the Runner target.
+//
+// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
+// future. If not, the values below would default to using the project name when this becomes a
+// 'flutter create' template.
+
+// The application's name. By default this is also the title of the Flutter window.
+PRODUCT_NAME = material_3_demo
+
+// The application's bundle identifier
+PRODUCT_BUNDLE_IDENTIFIER = com.example.material3Demo
+
+// The copyright displayed in application information
+PRODUCT_COPYRIGHT = Copyright © 2022 com.example. All rights reserved.

+ 2 - 0
macos/Runner/Configs/Debug.xcconfig

@@ -0,0 +1,2 @@
+#include "../../Flutter/Flutter-Debug.xcconfig"
+#include "Warnings.xcconfig"

+ 2 - 0
macos/Runner/Configs/Release.xcconfig

@@ -0,0 +1,2 @@
+#include "../../Flutter/Flutter-Release.xcconfig"
+#include "Warnings.xcconfig"

+ 13 - 0
macos/Runner/Configs/Warnings.xcconfig

@@ -0,0 +1,13 @@
+WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
+GCC_WARN_UNDECLARED_SELECTOR = YES
+CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
+CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
+CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
+CLANG_WARN_PRAGMA_PACK = YES
+CLANG_WARN_STRICT_PROTOTYPES = YES
+CLANG_WARN_COMMA = YES
+GCC_WARN_STRICT_SELECTOR_MATCH = YES
+CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
+CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
+GCC_WARN_SHADOW = YES
+CLANG_WARN_UNREACHABLE_CODE = YES

+ 12 - 0
macos/Runner/DebugProfile.entitlements

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>com.apple.security.app-sandbox</key>
+	<true/>
+	<key>com.apple.security.cs.allow-jit</key>
+	<true/>
+	<key>com.apple.security.network.server</key>
+	<true/>
+</dict>
+</plist>

+ 32 - 0
macos/Runner/Info.plist

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>$(DEVELOPMENT_LANGUAGE)</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>$(FLUTTER_BUILD_NAME)</string>
+	<key>CFBundleVersion</key>
+	<string>$(FLUTTER_BUILD_NUMBER)</string>
+	<key>LSMinimumSystemVersion</key>
+	<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
+	<key>NSHumanReadableCopyright</key>
+	<string>$(PRODUCT_COPYRIGHT)</string>
+	<key>NSMainNibFile</key>
+	<string>MainMenu</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+</dict>
+</plist>

+ 15 - 0
macos/Runner/MainFlutterWindow.swift

@@ -0,0 +1,15 @@
+import Cocoa
+import FlutterMacOS
+
+class MainFlutterWindow: NSWindow {
+  override func awakeFromNib() {
+    let flutterViewController = FlutterViewController.init()
+    let windowFrame = self.frame
+    self.contentViewController = flutterViewController
+    self.setFrame(windowFrame, display: true)
+
+    RegisterGeneratedPlugins(registry: flutterViewController)
+
+    super.awakeFromNib()
+  }
+}

+ 8 - 0
macos/Runner/Release.entitlements

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>com.apple.security.app-sandbox</key>
+	<true/>
+</dict>
+</plist>

+ 12 - 0
macos/RunnerTests/RunnerTests.swift

@@ -0,0 +1,12 @@
+import FlutterMacOS
+import Cocoa
+import XCTest
+
+class RunnerTests: XCTestCase {
+
+  func testExample() {
+    // If you add code to the Runner application, consider adding tests here.
+    // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
+  }
+
+}

Some files were not shown because too many files changed in this diff