diff --git a/.all-contributorsrc b/.all-contributorsrc deleted file mode 100644 index 98c387311..000000000 --- a/.all-contributorsrc +++ /dev/null @@ -1,92 +0,0 @@ -{ - "projectName": "mix", - "projectOwner": "conceptadev", - "repoType": "github", - "repoHost": "https://github.com", - "files": [ - "README.md" - ], - "imageSize": 50, - "commit": true, - "commitConvention": "eslint", - "contributors": [ - { - "login": "leoafarias", - "name": "Leo Farias", - "avatar_url": "https://avatars.githubusercontent.com/u/435833?v=4", - "profile": "https://github.com/leoafarias", - "contributions": [ - "ideas", - "code", - "doc" - ] - }, - { - "login": "bdlukaa", - "name": "Bruno D'Luka", - "avatar_url": "https://avatars.githubusercontent.com/u/45696119?v=4", - "profile": "https://github.com/bdlukaa", - "contributions": [ - "code" - ] - }, - { - "login": "rickbsgu", - "name": "Rick Berger", - "avatar_url": "https://avatars.githubusercontent.com/u/161474?v=4", - "profile": "https://github.com/rickbsgu", - "contributions": [ - "doc" - ] - }, - { - "login": "sbis04", - "name": "Souvik Biswas", - "avatar_url": "https://avatars.githubusercontent.com/u/43280874?v=4", - "profile": "https://github.com/sbis04", - "contributions": [ - "content", - "tutorial" - ] - }, - { - "login": "tilucasoli", - "name": "Lucas Oliveira", - "avatar_url": "https://avatars.githubusercontent.com/u/62367544?v=4", - "profile": "https://github.com/tilucasoli", - "contributions": [ - "code" - ] - }, - { - "login": "pbissonho", - "name": "Pedro Bissonho", - "avatar_url": "https://avatars.githubusercontent.com/u/43250625?v=4", - "profile": "https://www.linkedin.com/in/pedrobissonho/", - "contributions": [ - "code", - "ideas" - ] - }, - { - "login": "marcobraghim", - "name": "Marco A. Braghim", - "avatar_url": "https://avatars.githubusercontent.com/u/2068045?v=4", - "profile": "https://webstandapp.com.br", - "contributions": [ - "code" - ] - }, - { - "login": "aguilaair", - "name": "Eduardo M.", - "avatar_url": "https://avatars.githubusercontent.com/u/29983481?v=4", - "profile": "http://eduardom.dev", - "contributions": [ - "code" - ] - } - ], - "contributorsPerLine": 7, - "commitType": "docs" -} diff --git a/.fvmrc b/.fvmrc index c9e0c1af0..08dc7d2b4 100644 --- a/.fvmrc +++ b/.fvmrc @@ -3,5 +3,8 @@ "flavors": { "prod": "stable", "mincompat": "3.19.0" - } + }, + "runPubGetOnSdkChanges": true, + "updateVscodeSettings": true, + "updateGitIgnore": false } \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9abb118c0..96ec726a7 100644 --- a/.gitignore +++ b/.gitignore @@ -88,11 +88,11 @@ node_modules # FVM -# FVM Version Cache -.fvm/ - .packages .pub/ .dart_tool/ pubspec_overrides.yaml pubspec.lock + +# FVM Version Cache +.fvm/ \ No newline at end of file diff --git a/mix.code-workspace b/mix.code-workspace index 6c533fa66..7148b31e5 100644 --- a/mix.code-workspace +++ b/mix.code-workspace @@ -4,6 +4,10 @@ "name": "mix", "path": "packages/mix" }, + { + "name": "root", + "path": "." + }, { "name": "mix_generator", "path": "packages/mix_generator" @@ -17,8 +21,4 @@ "path": "packages/remix" } ], - "settings": {}, - "extensions": { - "recommendations": [] - } } diff --git a/packages/mix/lib/src/core/deprecation_notices.dart b/packages/mix/lib/src/core/deprecation_notices.dart index ffa90fe8e..dbebb5c91 100644 --- a/packages/mix/lib/src/core/deprecation_notices.dart +++ b/packages/mix/lib/src/core/deprecation_notices.dart @@ -1,10 +1,10 @@ // ignore_for_file: camel_case_types import '../attributes/enum/enum_util.dart'; +import '../core/internal/widget_state/widget_state.dart'; import '../specs/image/image_spec.dart'; import '../variants/widget_state_variant.dart'; import 'attribute.dart'; -import 'internal/widget_state/widget_state.dart'; class InternalMixDeprecatedAnnotation extends Deprecated { final String version; diff --git a/packages/mix/lib/src/theme/tokens/color_token.dart b/packages/mix/lib/src/theme/tokens/color_token.dart index ee9d988c3..2af5b37dd 100644 --- a/packages/mix/lib/src/theme/tokens/color_token.dart +++ b/packages/mix/lib/src/theme/tokens/color_token.dart @@ -24,6 +24,10 @@ class ColorToken extends MixToken { @override Color resolve(BuildContext context) { final themeValue = MixTheme.of(context).colors[this]; + + if (themeValue == null) { + // Look for maybe been a swatch token + } assert( themeValue != null, 'ColorToken $name is not defined in the theme', diff --git a/packages/remix/.vscode/launch.json b/packages/remix/.vscode/launch.json new file mode 100644 index 000000000..c68fc4769 --- /dev/null +++ b/packages/remix/.vscode/launch.json @@ -0,0 +1,30 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "name": "Remix (debug mode)", + "cwd": "demo", + "request": "launch", + "type": "dart", + "deviceId": "macos" + }, + { + "name": "Remix (profile mode)", + "cwd": "demo", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "Remix (release mode)", + "cwd": "demo", + "request": "launch", + "type": "dart", + "flutterMode": "release" + } + ] +} \ No newline at end of file diff --git a/packages/remix/LICENSE b/packages/remix/LICENSE new file mode 100644 index 000000000..deeda1dce --- /dev/null +++ b/packages/remix/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2022, Concepta +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/remix/README.md b/packages/remix/README.md new file mode 100644 index 000000000..9c5e05581 --- /dev/null +++ b/packages/remix/README.md @@ -0,0 +1,16 @@ +# remix_ui + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/packages/remix/analysis_options.yaml b/packages/remix/analysis_options.yaml new file mode 100644 index 000000000..099c1131f --- /dev/null +++ b/packages/remix/analysis_options.yaml @@ -0,0 +1,6 @@ +include: package:flutter_lints/flutter.yaml + +linter: + rules: + library_private_types_in_public_api: false + non_constant_identifier_names: false diff --git a/packages/remix/build.yaml b/packages/remix/build.yaml new file mode 100644 index 000000000..22a345582 --- /dev/null +++ b/packages/remix/build.yaml @@ -0,0 +1,9 @@ +targets: + $default: + builders: + mix_generator|spec: + generate_for: + - lib/**/*_spec.dart + mix_generator|dto: + generate_for: + - lib/**/*_dto.dart \ No newline at end of file diff --git a/packages/remix/demo/.gitignore b/packages/remix/demo/.gitignore new file mode 100644 index 000000000..29a3a5017 --- /dev/null +++ b/packages/remix/demo/.gitignore @@ -0,0 +1,43 @@ +# 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 +.pub-cache/ +.pub/ +/build/ + +# 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 diff --git a/packages/remix/demo/.metadata b/packages/remix/demo/.metadata new file mode 100644 index 000000000..de745e4a0 --- /dev/null +++ b/packages/remix/demo/.metadata @@ -0,0 +1,45 @@ +# 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: f468f3366c26a5092eb964a230ce7892fda8f2f8 + channel: stable + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + - platform: android + create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + - platform: ios + create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + - platform: linux + create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + - platform: macos + create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + - platform: web + create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + - platform: windows + create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 + + # 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' diff --git a/packages/remix/demo/README.md b/packages/remix/demo/README.md new file mode 100644 index 000000000..dbd403a00 --- /dev/null +++ b/packages/remix/demo/README.md @@ -0,0 +1,16 @@ +# demo + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/packages/remix/demo/analysis_options.yaml b/packages/remix/demo/analysis_options.yaml new file mode 100644 index 000000000..0d2902135 --- /dev/null +++ b/packages/remix/demo/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/packages/remix/demo/ios/.gitignore b/packages/remix/demo/ios/.gitignore new file mode 100644 index 000000000..7a7f9873a --- /dev/null +++ b/packages/remix/demo/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 diff --git a/packages/remix/demo/ios/Flutter/AppFrameworkInfo.plist b/packages/remix/demo/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 000000000..9625e105d --- /dev/null +++ b/packages/remix/demo/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 11.0 + + diff --git a/packages/remix/demo/ios/Flutter/Debug.xcconfig b/packages/remix/demo/ios/Flutter/Debug.xcconfig new file mode 100644 index 000000000..592ceee85 --- /dev/null +++ b/packages/remix/demo/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/packages/remix/demo/ios/Flutter/Release.xcconfig b/packages/remix/demo/ios/Flutter/Release.xcconfig new file mode 100644 index 000000000..592ceee85 --- /dev/null +++ b/packages/remix/demo/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/packages/remix/demo/ios/Runner.xcodeproj/project.pbxproj b/packages/remix/demo/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000..fd8d20931 --- /dev/null +++ b/packages/remix/demo/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,616 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + 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 */; }; + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy 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 = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 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 = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; +/* 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 = ""; + }; + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 331C8082294A63A400263BE5 /* RunnerTests */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 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 = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C807D294A63A400263BE5 /* Sources */, + 331C807E294A63A400263BE5 /* Frameworks */, + 331C807F294A63A400263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 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 = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + 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 */, + 331C8080294A63A400263BE5 /* RunnerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 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; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + 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; + alwaysOutOfDate = 1; + 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 */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* 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)"; + DEVELOPMENT_TEAM = RW3X256N25; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.demo; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AE0B7B92F70575B8D7E0D07E /* Pods-RunnerTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.demo.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 89B67EB44CE7B6631473024E /* Pods-RunnerTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.demo.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 640959BDD8F10B91D80A66BE /* Pods-RunnerTests.profile.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.demo.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + 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)"; + DEVELOPMENT_TEAM = RW3X256N25; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.demo; + 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)"; + DEVELOPMENT_TEAM = RW3X256N25; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.demo; + 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 */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 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 */; +} diff --git a/packages/remix/demo/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/remix/demo/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/packages/remix/demo/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/remix/demo/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/remix/demo/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/packages/remix/demo/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/remix/demo/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/remix/demo/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..f9b0d7c5e --- /dev/null +++ b/packages/remix/demo/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/packages/remix/demo/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/remix/demo/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000..e42adcb34 --- /dev/null +++ b/packages/remix/demo/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/remix/demo/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/remix/demo/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..1d526a16e --- /dev/null +++ b/packages/remix/demo/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/remix/demo/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/remix/demo/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/packages/remix/demo/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/remix/demo/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/remix/demo/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..f9b0d7c5e --- /dev/null +++ b/packages/remix/demo/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/packages/remix/demo/ios/Runner/AppDelegate.swift b/packages/remix/demo/ios/Runner/AppDelegate.swift new file mode 100644 index 000000000..70693e4a8 --- /dev/null +++ b/packages/remix/demo/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) + } +} diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..d36b1fab2 --- /dev/null +++ b/packages/remix/demo/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" + } +} diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 000000000..dc9ada472 Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 000000000..7353c41ec Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 000000000..797d452e4 Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 000000000..6ed2d933e Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 000000000..4cd7b0099 Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 000000000..fe730945a Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 000000000..321773cd8 Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 000000000..797d452e4 Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 000000000..502f463a9 Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 000000000..0ec303439 Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 000000000..0ec303439 Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 000000000..e9f5fea27 Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 000000000..84ac32ae7 Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 000000000..8953cba09 Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 000000000..0467bf12a Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/packages/remix/demo/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 000000000..0bedcf2fd --- /dev/null +++ b/packages/remix/demo/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" + } +} diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/packages/remix/demo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 000000000..9da19eaca Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 000000000..9da19eaca Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/remix/demo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 000000000..9da19eaca Binary files /dev/null and b/packages/remix/demo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/packages/remix/demo/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/packages/remix/demo/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 000000000..89c2725b7 --- /dev/null +++ b/packages/remix/demo/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. \ No newline at end of file diff --git a/packages/remix/demo/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/remix/demo/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..f2e259c7c --- /dev/null +++ b/packages/remix/demo/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/remix/demo/ios/Runner/Base.lproj/Main.storyboard b/packages/remix/demo/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 000000000..f3c28516f --- /dev/null +++ b/packages/remix/demo/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/remix/demo/ios/Runner/Info.plist b/packages/remix/demo/ios/Runner/Info.plist new file mode 100644 index 000000000..5d7841048 --- /dev/null +++ b/packages/remix/demo/ios/Runner/Info.plist @@ -0,0 +1,51 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Demo + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + demo + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + + diff --git a/packages/remix/demo/ios/Runner/Runner-Bridging-Header.h b/packages/remix/demo/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 000000000..308a2a560 --- /dev/null +++ b/packages/remix/demo/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/packages/remix/demo/ios/RunnerTests/RunnerTests.swift b/packages/remix/demo/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 000000000..86a7c3b1b --- /dev/null +++ b/packages/remix/demo/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +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. + } + +} diff --git a/packages/remix/demo/lib/addons/brightness_addon.dart b/packages/remix/demo/lib/addons/brightness_addon.dart new file mode 100644 index 000000000..d44074d95 --- /dev/null +++ b/packages/remix/demo/lib/addons/brightness_addon.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook/widgetbook.dart'; + +class BrightnessAddon extends WidgetbookAddon { + final Brightness initialBrightness; + + BrightnessAddon({ + this.initialBrightness = Brightness.light, + }) : super(name: 'Brightness'); + + @override + Widget buildUseCase( + BuildContext context, + Widget child, + Brightness setting, + ) { + return Theme( + data: ThemeData( + brightness: setting, + ), + child: child, + ); + } + + @override + List> get fields { + return [ + ListField( + name: 'brightness', + initialValue: initialBrightness, + values: [ + Brightness.light, + Brightness.dark, + ], + ) + ]; + } + + @override + Brightness valueFromQueryGroup(Map group) { + return valueOf('brightness', group)!; + } +} diff --git a/packages/remix/demo/lib/addons/icon_data_knob.dart b/packages/remix/demo/lib/addons/icon_data_knob.dart new file mode 100644 index 000000000..c6b3452e8 --- /dev/null +++ b/packages/remix/demo/lib/addons/icon_data_knob.dart @@ -0,0 +1,65 @@ +import 'package:flutter/material.dart'; +import 'package:widgetbook/widgetbook.dart'; + +enum IconDataEnum { + none, + home, + settings, + favorite, + add, + delete, +} + +class IconDataKnob extends Knob { + IconDataKnob({ + required super.label, + super.initialValue, + }); + + @override + List get fields => [ + ListField( + name: label, + initialValue: IconDataEnum.none, + labelBuilder: (value) => value.name, + values: IconDataEnum.values, + ), + ]; + + @override + IconData? valueFromQueryGroup(Map group) { + final iconDataString = group[label]; + if (iconDataString != null) { + final iconDataEnum = IconDataEnum.values.firstWhere( + (e) => e.toString() == 'IconDataEnum.$iconDataString', + orElse: () => IconDataEnum.home, + ); + return _iconDataFromEnum(iconDataEnum); + } + return null; + } + + IconData? _iconDataFromEnum(IconDataEnum iconDataEnum) { + return switch (iconDataEnum) { + IconDataEnum.home => Icons.home, + IconDataEnum.settings => Icons.settings, + IconDataEnum.favorite => Icons.favorite, + IconDataEnum.add => Icons.add, + IconDataEnum.delete => Icons.delete, + IconDataEnum.none => null, + }; + } +} + +extension IconDataKnobBuilder on KnobsBuilder { + IconData? iconData({ + required String label, + IconData? initialValue, + }) => + onKnobAdded( + IconDataKnob( + label: label, + initialValue: initialValue, + ), + ); +} diff --git a/packages/remix/demo/lib/components/avatar_use_case.dart b/packages/remix/demo/lib/components/avatar_use_case.dart new file mode 100644 index 000000000..0b85249ef --- /dev/null +++ b/packages/remix/demo/lib/components/avatar_use_case.dart @@ -0,0 +1,56 @@ +import 'package:flutter/material.dart'; +import 'package:remix/components/avatar/avatar_variants.dart'; +import 'package:remix/components/avatar/avatar_widget.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; + +final _key = GlobalKey(); + +@widgetbook.UseCase( + name: 'Avatar Component', + type: RxAvatar, +) +Widget buildAvatarUseCase(BuildContext context) { + final imageUrl = context.knobs.string( + label: 'Image URL', + initialValue: 'https://i.pravatar.cc/150?img=48', + ); + + Widget buildAvatar(AvatarVariant variant) { + return Column( + children: [ + Text(variant.name.split('.').last), + const SizedBox(height: 10), + RxAvatar( + image: NetworkImage(imageUrl), + fallback: context.knobs.string( + label: 'Fallback', + initialValue: 'AB', + ), + variant: variant, + size: context.knobs.list( + label: 'Size', + options: AvatarSize.values, + initialOption: AvatarSize.size4, + labelBuilder: (value) => value.name.split('.').last, + ), + radius: context.knobs.list( + label: 'Radius', + options: AvatarRadius.values, + initialOption: AvatarRadius.full, + labelBuilder: (value) => value.name.split('.').last, + ), + ), + ], + ); + } + + return KeyedSubtree( + key: _key, + child: Wrap( + spacing: 12, + runSpacing: 12, + children: AvatarVariant.values.map(buildAvatar).toList(), + ), + ); +} diff --git a/packages/remix/demo/lib/components/button_use_case.dart b/packages/remix/demo/lib/components/button_use_case.dart new file mode 100644 index 000000000..b89c06383 --- /dev/null +++ b/packages/remix/demo/lib/components/button_use_case.dart @@ -0,0 +1,49 @@ +import 'package:demo/addons/icon_data_knob.dart'; +import 'package:flutter/material.dart'; +import 'package:remix/remix.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; + +@widgetbook.UseCase( + name: 'Button Component', + type: RxButton, +) +Widget buildButtonUseCase(BuildContext context) { + Widget buildButton(ButtonVariant type) { + return RxButton( + label: context.knobs.string( + label: 'Title', + initialValue: 'Button', + ), + onPressed: () {}, + size: context.knobs.list( + label: 'Size', + options: ButtonSize.values, + initialOption: ButtonSize.medium, + labelBuilder: (value) => value.name.split('.').last, + ), + loading: context.knobs.boolean( + label: 'Is loading', + initialValue: false, + ), + disabled: context.knobs.boolean( + label: 'Disabled', + initialValue: false, + ), + iconLeft: context.knobs.iconData( + label: 'Icon left', + initialValue: null, + ), + iconRight: context.knobs.iconData( + label: 'Icon right', + initialValue: null, + ), + type: type, + ); + } + + return Wrap( + spacing: 12, + children: ButtonVariant.values.map(buildButton).toList(), + ); +} diff --git a/packages/remix/demo/lib/components/callout_use_case.dart b/packages/remix/demo/lib/components/callout_use_case.dart new file mode 100644 index 000000000..e1b400d2e --- /dev/null +++ b/packages/remix/demo/lib/components/callout_use_case.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; +import 'package:remix/components/callout/callout_variants.dart'; +import 'package:remix/components/callout/callout_widget.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; + +final _key = GlobalKey(); + +@widgetbook.UseCase( + name: 'Callout Component', + type: RxCallout, +) +Widget buildCalloutUseCase(BuildContext context) { + Widget buildCallout(CalloutVariant variant) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(variant.label), + const SizedBox(height: 10), + RxCallout( + icon: context.knobs.list( + label: 'Icon', + options: [ + Icons.info, + Icons.warning, + Icons.error, + Icons.check_circle, + ], + initialOption: Icons.info, + labelBuilder: (value) => value.toString().split('.').last, + ), + variant: variant, + text: context.knobs.string( + label: 'Text', + initialValue: 'Content for the callout goes here', + ), + ), + ], + ); + } + + return KeyedSubtree( + key: _key, + child: Column( + children: [ + Row( + mainAxisSize: MainAxisSize.max, + children: CalloutVariant.values.map(buildCallout).toList(), + ), + ], + ), + ); +} diff --git a/packages/remix/demo/lib/components/card_use_case.dart b/packages/remix/demo/lib/components/card_use_case.dart new file mode 100644 index 000000000..7c8bf34b5 --- /dev/null +++ b/packages/remix/demo/lib/components/card_use_case.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/remix.dart'; +import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; + +@widgetbook.UseCase( + name: 'Card Component', + type: RxCard, +) +Widget buildCard(BuildContext context) { + Widget buildCard(CardVariant variant) { + return Column( + children: [ + Text(variant.label), + const SizedBox(height: 10), + RxCard( + variant: variant, + children: const [StyledText('Hi'), StyledText('This is a test')], + ), + ], + ); + } + + return Wrap( + spacing: 12, + runSpacing: 12, + children: CardVariant.values.map(buildCard).toList(), + ); +} + +@widgetbook.UseCase( + name: 'With button', + type: RxCard, +) +Widget buildRadioUseCase(BuildContext context) { + Widget buildCard(CardVariant variant) { + return Column( + children: [ + Text(variant.label), + const SizedBox(height: 10), + RxCard( + variant: variant, + children: const [StyledText('Hi'), StyledText('This is a test')], + ), + const SizedBox(height: 10), + RxButton( + label: 'Click me', + onPressed: () {}, + ), + ], + ); + } + + return Wrap( + spacing: 12, + runSpacing: 12, + children: CardVariant.values.map(buildCard).toList(), + ); +} diff --git a/packages/remix/demo/lib/components/checkbox_use_case.dart b/packages/remix/demo/lib/components/checkbox_use_case.dart new file mode 100644 index 000000000..12e29dcf7 --- /dev/null +++ b/packages/remix/demo/lib/components/checkbox_use_case.dart @@ -0,0 +1,48 @@ +import 'package:demo/helpers/use_case_state.dart'; +import 'package:flutter/material.dart'; +import 'package:remix/remix.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; + +final _key = GlobalKey(); + +@widgetbook.UseCase( + name: 'Checkbox Component', + type: RxCheckbox, +) +Widget buildCheckboxUseCase(BuildContext context) { + final knobState = WidgetbookState.of(context); + + Widget buildCheckbox(CheckboxVariant variant) { + return Column( + children: [ + Text(variant.label), + const SizedBox(height: 10), + RxCheckbox( + value: context.knobs.boolean(label: 'Checked', initialValue: true), + onChanged: (value) => knobState.updateKnob('Checked', value), + variant: variant, + size: context.knobs.list( + label: 'Size', + options: CheckboxSize.values, + initialOption: CheckboxSize.medium, + labelBuilder: (value) => value.name.split('.').last, + ), + disabled: context.knobs.boolean( + label: 'Disabled', + initialValue: false, + ), + ), + ], + ); + } + + return KeyedSubtree( + key: _key, + child: Wrap( + spacing: 12, + runSpacing: 12, + children: CheckboxVariant.values.map(buildCheckbox).toList(), + ), + ); +} diff --git a/packages/remix/demo/lib/components/progress_use_case.dart b/packages/remix/demo/lib/components/progress_use_case.dart new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/packages/remix/demo/lib/components/progress_use_case.dart @@ -0,0 +1 @@ + diff --git a/packages/remix/demo/lib/components/radio_use_case.dart b/packages/remix/demo/lib/components/radio_use_case.dart new file mode 100644 index 000000000..60ba33ec1 --- /dev/null +++ b/packages/remix/demo/lib/components/radio_use_case.dart @@ -0,0 +1,44 @@ +import 'package:demo/helpers/use_case_state.dart'; +import 'package:flutter/material.dart'; +import 'package:remix/components/radio/radio_variants.dart'; +import 'package:remix/components/radio/radio_widget.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; + +@widgetbook.UseCase( + name: 'Radio Component', + type: RxRadio, +) +Widget buildRadioUseCase(BuildContext context) { + final knobState = WidgetbookState.of(context); + + Widget buildRadio(RadioVariant variant) { + return Column( + children: [ + Text(variant.label), + const SizedBox(height: 10), + RxRadio( + value: context.knobs.boolean(label: 'Selected', initialValue: true), + onChanged: (value) => knobState.updateKnob('Selected', value), + variant: variant, + size: context.knobs.list( + label: 'Size', + options: RadioSize.values, + initialOption: RadioSize.medium, + labelBuilder: (value) => value.label, + ), + disabled: context.knobs.boolean( + label: 'Disabled', + initialValue: false, + ), + ), + ], + ); + } + + return Wrap( + spacing: 12, + runSpacing: 12, + children: RadioVariant.values.map(buildRadio).toList(), + ); +} diff --git a/packages/remix/demo/lib/components/spinner_use_case.dart b/packages/remix/demo/lib/components/spinner_use_case.dart new file mode 100644 index 000000000..ea080d910 --- /dev/null +++ b/packages/remix/demo/lib/components/spinner_use_case.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/spinner/spinner.variants.dart'; +import 'package:remix/components/spinner/spinner_spec.dart'; +import 'package:remix/components/spinner/spinner_widget.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; + +@widgetbook.UseCase( + name: 'Spinner Component', + type: RxSpinner, +) +Widget buildSpinnerUseCase(BuildContext context) { + Widget buildSpinner(SpinnerStyle style) { + return Column( + children: [ + Text(style.name), + const SizedBox(height: 10), + RxSpinner( + style: Style( + SpinnerSpecUtility.self.style(style), + ), + size: context.knobs.list( + label: 'Size', + options: SpinnerSize.values, + initialOption: SpinnerSize.medium, + labelBuilder: (value) => value.label, + ), + ), + ], + ); + } + + return Wrap( + spacing: 12, + runSpacing: 12, + children: SpinnerStyle.values.map(buildSpinner).toList(), + ); +} diff --git a/packages/remix/demo/lib/components/switch_use_case.dart b/packages/remix/demo/lib/components/switch_use_case.dart new file mode 100644 index 000000000..8ca9d6a0f --- /dev/null +++ b/packages/remix/demo/lib/components/switch_use_case.dart @@ -0,0 +1,49 @@ +import 'package:demo/helpers/use_case_state.dart'; +import 'package:flutter/material.dart'; +import 'package:remix/components/switch/switch_variants.dart'; +import 'package:remix/components/switch/switch_widget.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; + +final _key = GlobalKey(); + +@widgetbook.UseCase( + name: 'Switch Component', + type: RxSwitch, +) +Widget buildSwitchUseCase(BuildContext context) { + final knobState = WidgetbookState.of(context); + + Widget buildSwitch(SwitchVariant variant) { + return Column( + children: [ + Text(variant.label), + const SizedBox(height: 10), + RxSwitch( + value: context.knobs.boolean(label: 'Toggle', initialValue: true), + onChanged: (value) => knobState.updateKnob('Toggle', value), + variant: variant, + size: context.knobs.list( + label: 'Size', + options: SwitchSize.values, + initialOption: SwitchSize.medium, + labelBuilder: (value) => value.label, + ), + disabled: context.knobs.boolean( + label: 'Disabled', + initialValue: false, + ), + ), + ], + ); + } + + return KeyedSubtree( + key: _key, + child: Wrap( + spacing: 12, + runSpacing: 12, + children: SwitchVariant.values.map(buildSwitch).toList(), + ), + ); +} diff --git a/packages/remix/demo/lib/helpers/use_case_state.dart b/packages/remix/demo/lib/helpers/use_case_state.dart new file mode 100644 index 000000000..5a652e725 --- /dev/null +++ b/packages/remix/demo/lib/helpers/use_case_state.dart @@ -0,0 +1,11 @@ +import 'package:widgetbook/widgetbook.dart'; + +extension WidgetBookStateX on WidgetbookState { + void updateKnob(String label, T value) { + updateQueryField( + group: 'knobs', + field: label, + value: '$value', + ); + } +} diff --git a/packages/remix/demo/lib/main.dart b/packages/remix/demo/lib/main.dart new file mode 100644 index 000000000..6db213484 --- /dev/null +++ b/packages/remix/demo/lib/main.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:remix/remix.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; + +import 'main.directories.g.dart'; + +@widgetbook.App() +void main() { + runApp(const HotReload()); +} + +class HotReload extends StatelessWidget { + const HotReload({super.key}); + + @override + Widget build(BuildContext context) { + return Widgetbook.material( + addons: [ + MaterialThemeAddon( + themes: [ + WidgetbookTheme( + name: 'Light', + data: ThemeData.light(), + ), + WidgetbookTheme( + name: 'Dark', + data: ThemeData.dark(), + ), + ], + initialTheme: WidgetbookTheme( + name: 'Dark', + data: ThemeData.dark(), + ), + ), + BuilderAddon( + name: 'Remix Tokens', + builder: (context, child) { + final isDarkTheme = Theme.of(context).brightness == Brightness.dark; + return RemixTokens( + data: isDarkTheme ? RemixTokens.dark : RemixTokens.light, + child: Container( + color: isDarkTheme ? Colors.black87 : Colors.white, + child: Center(child: child), + ), + ); + }, + ), + InspectorAddon(), + ], + appBuilder: (context, child) => MaterialApp( + debugShowCheckedModeBanner: false, + home: Scaffold(body: Center(child: child)), + ), + directories: directories, + ); + } +} diff --git a/packages/remix/demo/lib/main.directories.g.dart b/packages/remix/demo/lib/main.directories.g.dart new file mode 100644 index 000000000..c2a5e7634 --- /dev/null +++ b/packages/remix/demo/lib/main.directories.g.dart @@ -0,0 +1,130 @@ +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_import, prefer_relative_imports, directives_ordering + +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// AppGenerator +// ************************************************************************** + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:demo/components/avatar_use_case.dart' as _i2; +import 'package:demo/components/button_use_case.dart' as _i3; +import 'package:demo/components/callout_use_case.dart' as _i4; +import 'package:demo/components/card_use_case.dart' as _i5; +import 'package:demo/components/checkbox_use_case.dart' as _i6; +import 'package:demo/components/radio_use_case.dart' as _i7; +import 'package:demo/components/spinner_use_case.dart' as _i8; +import 'package:demo/components/switch_use_case.dart' as _i9; +import 'package:widgetbook/widgetbook.dart' as _i1; + +final directories = <_i1.WidgetbookNode>[ + _i1.WidgetbookFolder( + name: 'components', + children: [ + _i1.WidgetbookFolder( + name: 'avatar', + children: [ + _i1.WidgetbookLeafComponent( + name: 'RxAvatar', + useCase: _i1.WidgetbookUseCase( + name: 'Avatar Component', + builder: _i2.buildAvatarUseCase, + ), + ) + ], + ), + _i1.WidgetbookFolder( + name: 'button', + children: [ + _i1.WidgetbookLeafComponent( + name: 'RxButton', + useCase: _i1.WidgetbookUseCase( + name: 'Button Component', + builder: _i3.buildButtonUseCase, + ), + ) + ], + ), + _i1.WidgetbookFolder( + name: 'callout', + children: [ + _i1.WidgetbookLeafComponent( + name: 'RxCallout', + useCase: _i1.WidgetbookUseCase( + name: 'Callout Component', + builder: _i4.buildCalloutUseCase, + ), + ) + ], + ), + _i1.WidgetbookFolder( + name: 'card', + children: [ + _i1.WidgetbookComponent( + name: 'RxCard', + useCases: [ + _i1.WidgetbookUseCase( + name: 'Card Component', + builder: _i5.buildCard, + ), + _i1.WidgetbookUseCase( + name: 'With button', + builder: _i5.buildRadioUseCase, + ), + ], + ) + ], + ), + _i1.WidgetbookFolder( + name: 'checkbox', + children: [ + _i1.WidgetbookLeafComponent( + name: 'RxCheckbox', + useCase: _i1.WidgetbookUseCase( + name: 'Checkbox Component', + builder: _i6.buildCheckboxUseCase, + ), + ) + ], + ), + _i1.WidgetbookFolder( + name: 'radio', + children: [ + _i1.WidgetbookLeafComponent( + name: 'RxRadio', + useCase: _i1.WidgetbookUseCase( + name: 'Radio Component', + builder: _i7.buildRadioUseCase, + ), + ) + ], + ), + _i1.WidgetbookFolder( + name: 'spinner', + children: [ + _i1.WidgetbookLeafComponent( + name: 'RxSpinner', + useCase: _i1.WidgetbookUseCase( + name: 'Spinner Component', + builder: _i8.buildSpinnerUseCase, + ), + ) + ], + ), + _i1.WidgetbookFolder( + name: 'switch', + children: [ + _i1.WidgetbookLeafComponent( + name: 'RxSwitch', + useCase: _i1.WidgetbookUseCase( + name: 'Switch Component', + builder: _i9.buildSwitchUseCase, + ), + ) + ], + ), + ], + ) +]; diff --git a/packages/remix/demo/linux/.gitignore b/packages/remix/demo/linux/.gitignore new file mode 100644 index 000000000..d3896c984 --- /dev/null +++ b/packages/remix/demo/linux/.gitignore @@ -0,0 +1 @@ +flutter/ephemeral diff --git a/packages/remix/demo/linux/CMakeLists.txt b/packages/remix/demo/linux/CMakeLists.txt new file mode 100644 index 000000000..d8d150acd --- /dev/null +++ b/packages/remix/demo/linux/CMakeLists.txt @@ -0,0 +1,139 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.10) +project(runner LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "demo") +# The unique GTK application identifier for this application. See: +# https://wiki.gnome.org/HowDoI/ChooseApplicationID +set(APPLICATION_ID "com.example.demo") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(SET CMP0063 NEW) + +# Load bundled libraries from the lib/ directory relative to the binary. +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Root filesystem for cross-building. +if(FLUTTER_TARGET_PLATFORM_SYSROOT) + set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endif() + +# Define build configuration options. +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") +endif() + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_14) + target_compile_options(${TARGET} PRIVATE -Wall -Werror) + target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") + target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) + +add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") + +# Define the application target. To change its name, change BINARY_NAME above, +# not the value here, or `flutter run` will no longer work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} + "main.cc" + "my_application.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add dependency libraries. Add any application-specific dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) + +# Only the install-generated bundle's copy of the executable will launch +# correctly, since the resources must in the right relative locations. To avoid +# people trying to run the unbundled copy, put it in a subdirectory instead of +# the default top-level location. +set_target_properties(${BINARY_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" +) + + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# By default, "installing" just makes a relocatable bundle in the build +# directory. +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +# Start with a clean build bundle directory every time. +install(CODE " + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") + " COMPONENT Runtime) + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) + install(FILES "${bundled_library}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endforeach(bundled_library) + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") + install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() diff --git a/packages/remix/demo/linux/flutter/CMakeLists.txt b/packages/remix/demo/linux/flutter/CMakeLists.txt new file mode 100644 index 000000000..d5bd01648 --- /dev/null +++ b/packages/remix/demo/linux/flutter/CMakeLists.txt @@ -0,0 +1,88 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.10) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. + +# Serves the same purpose as list(TRANSFORM ... PREPEND ...), +# which isn't available in 3.10. +function(list_prepend LIST_NAME PREFIX) + set(NEW_LIST "") + foreach(element ${${LIST_NAME}}) + list(APPEND NEW_LIST "${PREFIX}${element}") + endforeach(element) + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) +endfunction() + +# === Flutter Library === +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) +pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) + +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "fl_basic_message_channel.h" + "fl_binary_codec.h" + "fl_binary_messenger.h" + "fl_dart_project.h" + "fl_engine.h" + "fl_json_message_codec.h" + "fl_json_method_codec.h" + "fl_message_codec.h" + "fl_method_call.h" + "fl_method_channel.h" + "fl_method_codec.h" + "fl_method_response.h" + "fl_plugin_registrar.h" + "fl_plugin_registry.h" + "fl_standard_message_codec.h" + "fl_standard_method_codec.h" + "fl_string_codec.h" + "fl_value.h" + "fl_view.h" + "flutter_linux.h" +) +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") +target_link_libraries(flutter INTERFACE + PkgConfig::GTK + PkgConfig::GLIB + PkgConfig::GIO +) +add_dependencies(flutter flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/_phony_ + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" + ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} +) diff --git a/packages/remix/demo/linux/flutter/generated_plugin_registrant.cc b/packages/remix/demo/linux/flutter/generated_plugin_registrant.cc new file mode 100644 index 000000000..e71a16d23 --- /dev/null +++ b/packages/remix/demo/linux/flutter/generated_plugin_registrant.cc @@ -0,0 +1,11 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + + +void fl_register_plugins(FlPluginRegistry* registry) { +} diff --git a/packages/remix/demo/linux/flutter/generated_plugin_registrant.h b/packages/remix/demo/linux/flutter/generated_plugin_registrant.h new file mode 100644 index 000000000..e0f0a47bc --- /dev/null +++ b/packages/remix/demo/linux/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void fl_register_plugins(FlPluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/packages/remix/demo/linux/flutter/generated_plugins.cmake b/packages/remix/demo/linux/flutter/generated_plugins.cmake new file mode 100644 index 000000000..2e1de87a7 --- /dev/null +++ b/packages/remix/demo/linux/flutter/generated_plugins.cmake @@ -0,0 +1,23 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/packages/remix/demo/linux/main.cc b/packages/remix/demo/linux/main.cc new file mode 100644 index 000000000..e7c5c5437 --- /dev/null +++ b/packages/remix/demo/linux/main.cc @@ -0,0 +1,6 @@ +#include "my_application.h" + +int main(int argc, char** argv) { + g_autoptr(MyApplication) app = my_application_new(); + return g_application_run(G_APPLICATION(app), argc, argv); +} diff --git a/packages/remix/demo/linux/my_application.cc b/packages/remix/demo/linux/my_application.cc new file mode 100644 index 000000000..0d6f1ccec --- /dev/null +++ b/packages/remix/demo/linux/my_application.cc @@ -0,0 +1,104 @@ +#include "my_application.h" + +#include +#ifdef GDK_WINDOWING_X11 +#include +#endif + +#include "flutter/generated_plugin_registrant.h" + +struct _MyApplication { + GtkApplication parent_instance; + char** dart_entrypoint_arguments; +}; + +G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) + +// Implements GApplication::activate. +static void my_application_activate(GApplication* application) { + MyApplication* self = MY_APPLICATION(application); + GtkWindow* window = + GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + + // Use a header bar when running in GNOME as this is the common style used + // by applications and is the setup most users will be using (e.g. Ubuntu + // desktop). + // If running on X and not using GNOME then just use a traditional title bar + // in case the window manager does more exotic layout, e.g. tiling. + // If running on Wayland assume the header bar will work (may need changing + // if future cases occur). + gboolean use_header_bar = TRUE; +#ifdef GDK_WINDOWING_X11 + GdkScreen* screen = gtk_window_get_screen(window); + if (GDK_IS_X11_SCREEN(screen)) { + const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); + if (g_strcmp0(wm_name, "GNOME Shell") != 0) { + use_header_bar = FALSE; + } + } +#endif + if (use_header_bar) { + GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); + gtk_widget_show(GTK_WIDGET(header_bar)); + gtk_header_bar_set_title(header_bar, "demo"); + gtk_header_bar_set_show_close_button(header_bar, TRUE); + gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); + } else { + gtk_window_set_title(window, "demo"); + } + + gtk_window_set_default_size(window, 1280, 720); + gtk_widget_show(GTK_WIDGET(window)); + + g_autoptr(FlDartProject) project = fl_dart_project_new(); + fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); + + FlView* view = fl_view_new(project); + gtk_widget_show(GTK_WIDGET(view)); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); + + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + + gtk_widget_grab_focus(GTK_WIDGET(view)); +} + +// Implements GApplication::local_command_line. +static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { + MyApplication* self = MY_APPLICATION(application); + // Strip out the first argument as it is the binary name. + self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); + + g_autoptr(GError) error = nullptr; + if (!g_application_register(application, nullptr, &error)) { + g_warning("Failed to register: %s", error->message); + *exit_status = 1; + return TRUE; + } + + g_application_activate(application); + *exit_status = 0; + + return TRUE; +} + +// Implements GObject::dispose. +static void my_application_dispose(GObject* object) { + MyApplication* self = MY_APPLICATION(object); + g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); + G_OBJECT_CLASS(my_application_parent_class)->dispose(object); +} + +static void my_application_class_init(MyApplicationClass* klass) { + G_APPLICATION_CLASS(klass)->activate = my_application_activate; + G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; + G_OBJECT_CLASS(klass)->dispose = my_application_dispose; +} + +static void my_application_init(MyApplication* self) {} + +MyApplication* my_application_new() { + return MY_APPLICATION(g_object_new(my_application_get_type(), + "application-id", APPLICATION_ID, + "flags", G_APPLICATION_NON_UNIQUE, + nullptr)); +} diff --git a/packages/remix/demo/linux/my_application.h b/packages/remix/demo/linux/my_application.h new file mode 100644 index 000000000..72271d5e4 --- /dev/null +++ b/packages/remix/demo/linux/my_application.h @@ -0,0 +1,18 @@ +#ifndef FLUTTER_MY_APPLICATION_H_ +#define FLUTTER_MY_APPLICATION_H_ + +#include + +G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, + GtkApplication) + +/** + * my_application_new: + * + * Creates a new Flutter-based application. + * + * Returns: a new #MyApplication. + */ +MyApplication* my_application_new(); + +#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/packages/remix/demo/macos/.gitignore b/packages/remix/demo/macos/.gitignore new file mode 100644 index 000000000..746adbb6b --- /dev/null +++ b/packages/remix/demo/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/packages/remix/demo/macos/Flutter/Flutter-Debug.xcconfig b/packages/remix/demo/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 000000000..c2efd0b60 --- /dev/null +++ b/packages/remix/demo/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/remix/demo/macos/Flutter/Flutter-Release.xcconfig b/packages/remix/demo/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 000000000..c2efd0b60 --- /dev/null +++ b/packages/remix/demo/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/remix/demo/macos/Flutter/GeneratedPluginRegistrant.swift b/packages/remix/demo/macos/Flutter/GeneratedPluginRegistrant.swift new file mode 100644 index 000000000..cccf817a5 --- /dev/null +++ b/packages/remix/demo/macos/Flutter/GeneratedPluginRegistrant.swift @@ -0,0 +1,10 @@ +// +// Generated file. Do not edit. +// + +import FlutterMacOS +import Foundation + + +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { +} diff --git a/packages/remix/demo/macos/Flutter/ephemeral/Flutter-Generated.xcconfig b/packages/remix/demo/macos/Flutter/ephemeral/Flutter-Generated.xcconfig new file mode 100644 index 000000000..c39bb69fd --- /dev/null +++ b/packages/remix/demo/macos/Flutter/ephemeral/Flutter-Generated.xcconfig @@ -0,0 +1,13 @@ +// This is a generated file; do not edit or check into version control. +FLUTTER_ROOT=/Users/leofarias/fvm/versions/3.19.0 +FLUTTER_APPLICATION_PATH=/Users/leofarias/Projects/mix/packages/remix/demo +COCOAPODS_PARALLEL_CODE_SIGN=true +FLUTTER_TARGET=/Users/leofarias/Projects/mix/packages/remix/demo/lib/main.dart +FLUTTER_BUILD_DIR=build +FLUTTER_BUILD_NAME=1.0.0 +FLUTTER_BUILD_NUMBER=1 +DART_DEFINES=RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==,RkxVVFRFUl9XRUJfQ0FOVkFTS0lUX1VSTD1odHRwczovL3d3dy5nc3RhdGljLmNvbS9mbHV0dGVyLWNhbnZhc2tpdC8wNDgxN2M5OWM5ZmQ0OTU2ZjI3NTA1MjA0ZjdlMzQ0MzM1ODEwYWVkLw== +DART_OBFUSCATION=false +TRACK_WIDGET_CREATION=true +TREE_SHAKE_ICONS=false +PACKAGE_CONFIG=/Users/leofarias/Projects/mix/packages/remix/demo/.dart_tool/package_config.json diff --git a/packages/remix/demo/macos/Flutter/ephemeral/FlutterInputs.xcfilelist b/packages/remix/demo/macos/Flutter/ephemeral/FlutterInputs.xcfilelist index b8f66e7fd..390c10104 100644 --- a/packages/remix/demo/macos/Flutter/ephemeral/FlutterInputs.xcfilelist +++ b/packages/remix/demo/macos/Flutter/ephemeral/FlutterInputs.xcfilelist @@ -1,4 +1,4 @@ -/Users/leofarias/.pub-cache/hosted/pub.dev/_fe_analyzer_shared-64.0.0/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/_fe_analyzer_shared-67.0.0/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/accessibility_tools-1.0.0/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/accessibility_tools-1.0.0/lib/accessibility_tools.dart /Users/leofarias/.pub-cache/hosted/pub.dev/accessibility_tools-1.0.0/lib/src/accessibility_issue.dart @@ -10,8 +10,8 @@ /Users/leofarias/.pub-cache/hosted/pub.dev/accessibility_tools-1.0.0/lib/src/checkers/minimum_tap_area_checker.dart /Users/leofarias/.pub-cache/hosted/pub.dev/accessibility_tools-1.0.0/lib/src/checkers/mixin.dart /Users/leofarias/.pub-cache/hosted/pub.dev/accessibility_tools-1.0.0/lib/src/checkers/semantic_label_checker.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/analyzer-6.2.0/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/args-2.4.2/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/analyzer-6.4.1/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/args-2.5.0/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/async-2.11.0/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/async-2.11.0/lib/async.dart /Users/leofarias/.pub-cache/hosted/pub.dev/async-2.11.0/lib/src/async_cache.dart @@ -76,10 +76,10 @@ /Users/leofarias/.pub-cache/hosted/pub.dev/build_config-1.1.1/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/build_daemon-4.0.1/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/build_resolvers-2.4.2/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/build_runner-2.4.8/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/build_runner-2.4.9/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/build_runner_core-7.3.0/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/built_collection-5.1.1/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/built_value-8.9.1/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/built_value-8.9.2/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/characters-1.3.0/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/characters-1.3.0/lib/characters.dart /Users/leofarias/.pub-cache/hosted/pub.dev/characters-1.3.0/lib/src/characters.dart @@ -96,35 +96,35 @@ /Users/leofarias/.pub-cache/hosted/pub.dev/clock-1.1.1/lib/src/stopwatch.dart /Users/leofarias/.pub-cache/hosted/pub.dev/clock-1.1.1/lib/src/utils.dart /Users/leofarias/.pub-cache/hosted/pub.dev/code_builder-4.10.0/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/collection.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/algorithms.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/boollist.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/canonicalized_map.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/combined_wrappers/combined_iterable.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/combined_wrappers/combined_iterator.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/combined_wrappers/combined_list.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/combined_wrappers/combined_map.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/comparators.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/empty_unmodifiable_set.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/equality.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/equality_map.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/equality_set.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/functions.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/iterable_extensions.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/iterable_zip.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/list_extensions.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/priority_queue.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/queue_list.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/union_set.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/union_set_controller.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/unmodifiable_wrappers.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/utils.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.17.1/lib/src/wrappers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/collection.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/algorithms.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/boollist.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/canonicalized_map.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/combined_wrappers/combined_iterable.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/combined_wrappers/combined_iterator.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/combined_wrappers/combined_list.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/combined_wrappers/combined_map.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/comparators.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/empty_unmodifiable_set.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/equality.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/equality_map.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/equality_set.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/functions.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/iterable_extensions.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/iterable_zip.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/list_extensions.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/priority_queue.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/queue_list.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/union_set.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/union_set_controller.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/unmodifiable_wrappers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/utils.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/collection-1.18.0/lib/src/wrappers.dart /Users/leofarias/.pub-cache/hosted/pub.dev/convert-3.1.1/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/crypto-3.0.3/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/cupertino_icons-1.0.6/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/cupertino_icons-1.0.6/assets/CupertinoIcons.ttf +/Users/leofarias/.pub-cache/hosted/pub.dev/cupertino_icons-1.0.8/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/cupertino_icons-1.0.8/assets/CupertinoIcons.ttf /Users/leofarias/.pub-cache/hosted/pub.dev/dart_style-2.3.6/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/device_frame-1.1.0/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/device_frame-1.1.0/lib/device_frame.dart @@ -213,10 +213,10 @@ /Users/leofarias/.pub-cache/hosted/pub.dev/file-7.0.0/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/fixnum-1.1.0/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/flutter_lints-2.0.3/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/freezed_annotation-2.4.1/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/freezed_annotation-2.4.1/lib/freezed_annotation.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/freezed_annotation-2.4.1/lib/freezed_annotation.g.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/frontend_server_client-3.2.0/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/freezed_annotation-2.4.3/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/freezed_annotation-2.4.3/lib/freezed_annotation.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/freezed_annotation-2.4.3/lib/freezed_annotation.g.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/frontend_server_client-4.0.0/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/glob-2.1.2/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/graphs-2.3.1/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/http_multi_server-3.2.1/LICENSE @@ -239,97 +239,152 @@ /Users/leofarias/.pub-cache/hosted/pub.dev/inspector-2.1.0/lib/src/widgets/panel/inspector_panel.dart /Users/leofarias/.pub-cache/hosted/pub.dev/inspector-2.1.0/lib/src/widgets/zoom/zoom_overlay.dart /Users/leofarias/.pub-cache/hosted/pub.dev/io-1.0.4/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/js-0.6.7/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.8.1/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.8.1/lib/json_annotation.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.8.1/lib/src/allowed_keys_helpers.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.8.1/lib/src/checked_helpers.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.8.1/lib/src/enum_helpers.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.8.1/lib/src/json_converter.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.8.1/lib/src/json_enum.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.8.1/lib/src/json_key.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.8.1/lib/src/json_literal.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.8.1/lib/src/json_serializable.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.8.1/lib/src/json_serializable.g.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.8.1/lib/src/json_value.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/js-0.7.1/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.9.0/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.9.0/lib/json_annotation.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.9.0/lib/src/allowed_keys_helpers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.9.0/lib/src/checked_helpers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.9.0/lib/src/enum_helpers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.9.0/lib/src/json_converter.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.9.0/lib/src/json_enum.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.9.0/lib/src/json_key.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.9.0/lib/src/json_literal.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.9.0/lib/src/json_serializable.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.9.0/lib/src/json_serializable.g.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/json_annotation-4.9.0/lib/src/json_value.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/leak_tracker.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/devtools_integration/_protocol.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/devtools_integration/_registration.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/devtools_integration/delivery.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/devtools_integration/messages.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/devtools_integration/primitives.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/_baseliner.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/_leak_filter.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/_leak_reporter.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/_leak_tracker.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/_object_record.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/_object_record_set.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/_object_records.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/_object_tracker.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/helpers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/leak_tracking.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/primitives/_dispatcher.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/primitives/_finalizer.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/primitives/_gc_counter.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/primitives/_print_bytes.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/primitives/_retaining_path/_connection.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/primitives/_retaining_path/_retaining_path.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/primitives/_retaining_path/_retaining_path_isolate.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/leak_tracking/primitives/model.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/shared/_formatting.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/shared/_primitives.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/shared/_util.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker-10.0.0/lib/src/shared/shared_model.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker_flutter_testing-2.0.1/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker_flutter_testing-2.0.1/lib/leak_tracker_flutter_testing.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker_flutter_testing-2.0.1/lib/src/matchers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker_flutter_testing-2.0.1/lib/src/model.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker_flutter_testing-2.0.1/lib/src/testing.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker_testing-2.0.1/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker_testing-2.0.1/lib/leak_tracker_testing.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker_testing-2.0.1/lib/src/leak_testing.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/leak_tracker_testing-2.0.1/lib/src/matchers.dart /Users/leofarias/.pub-cache/hosted/pub.dev/lints-2.1.1/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/logging-1.2.0/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/expect.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/matcher.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/core_matchers.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/custom_matcher.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/description.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/equals_matcher.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/error_matchers.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/expect/async_matcher.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/expect/expect.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/expect/expect_async.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/expect/future_matchers.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/expect/never_called.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/expect/prints_matcher.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/expect/stream_matcher.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/expect/stream_matchers.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/expect/throws_matcher.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/expect/throws_matchers.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/expect/util/placeholder.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/expect/util/pretty_print.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/feature_matcher.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/having_matcher.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/interfaces.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/iterable_matchers.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/map_matchers.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/numeric_matchers.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/operator_matchers.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/order_matchers.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/pretty_print.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/string_matchers.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/type_matcher.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib/src/util.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/blend/blend.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/hct/cam16.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/hct/hct.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/hct/hct_solver.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/hct/viewing_conditions.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/material_color_utilities.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/palettes/core_palette.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/palettes/tonal_palette.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/quantize/point_provider.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/quantize/point_provider_lab.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/quantize/quantizer.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/quantize/quantizer_celebi.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/quantize/quantizer_map.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/quantize/quantizer_wsmeans.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/quantize/quantizer_wu.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/scheme/scheme.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/score/score.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/utils/color_utils.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib/utils/math_utils.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/meta-1.9.1/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/meta-1.9.1/lib/meta.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/meta-1.9.1/lib/meta_meta.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/mime-1.0.4/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/expect.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/matcher.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/core_matchers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/custom_matcher.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/description.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/equals_matcher.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/error_matchers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/expect/async_matcher.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/expect/expect.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/expect/expect_async.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/expect/future_matchers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/expect/never_called.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/expect/prints_matcher.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/expect/stream_matcher.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/expect/stream_matchers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/expect/throws_matcher.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/expect/throws_matchers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/expect/util/placeholder.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/expect/util/pretty_print.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/feature_matcher.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/having_matcher.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/interfaces.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/iterable_matchers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/map_matchers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/numeric_matchers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/operator_matchers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/order_matchers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/pretty_print.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/string_matchers.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/type_matcher.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/matcher-0.12.16+1/lib/src/util.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/blend/blend.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/contrast/contrast.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/dislike/dislike_analyzer.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/dynamiccolor/dynamic_color.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/dynamiccolor/material_dynamic_colors.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/dynamiccolor/src/contrast_curve.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/dynamiccolor/src/tone_delta_pair.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/hct/cam16.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/hct/hct.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/hct/src/hct_solver.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/hct/viewing_conditions.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/material_color_utilities.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/palettes/core_palette.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/palettes/tonal_palette.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/quantize/quantizer.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/quantize/quantizer_celebi.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/quantize/quantizer_map.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/quantize/quantizer_wsmeans.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/quantize/quantizer_wu.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/quantize/src/point_provider.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/quantize/src/point_provider_lab.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/scheme/dynamic_scheme.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/scheme/scheme.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/scheme/scheme_content.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/scheme/scheme_expressive.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/scheme/scheme_fidelity.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/scheme/scheme_monochrome.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/scheme/scheme_neutral.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/scheme/scheme_tonal_spot.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/scheme/scheme_vibrant.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/scheme/variant.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/score/score.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/temperature/temperature_cache.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/utils/color_utils.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/utils/math_utils.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/material_color_utilities-0.8.0/lib/utils/string_utils.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/meta-1.11.0/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/meta-1.11.0/lib/meta.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/meta-1.11.0/lib/meta_meta.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/mime-1.0.5/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/nested-1.0.0/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/nested-1.0.0/lib/nested.dart /Users/leofarias/.pub-cache/hosted/pub.dev/package_config-2.1.0/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.8.3/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.8.3/lib/path.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.8.3/lib/src/characters.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.8.3/lib/src/context.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.8.3/lib/src/internal_style.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.8.3/lib/src/parsed_path.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.8.3/lib/src/path_exception.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.8.3/lib/src/path_map.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.8.3/lib/src/path_set.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.8.3/lib/src/style.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.8.3/lib/src/style/posix.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.8.3/lib/src/style/url.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.8.3/lib/src/style/windows.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.8.3/lib/src/utils.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.9.0/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.9.0/lib/path.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.9.0/lib/src/characters.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.9.0/lib/src/context.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.9.0/lib/src/internal_style.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.9.0/lib/src/parsed_path.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.9.0/lib/src/path_exception.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.9.0/lib/src/path_map.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.9.0/lib/src/path_set.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.9.0/lib/src/style.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.9.0/lib/src/style/posix.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.9.0/lib/src/style/url.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.9.0/lib/src/style/windows.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/path-1.9.0/lib/src/utils.dart /Users/leofarias/.pub-cache/hosted/pub.dev/pool-1.5.1/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/pub_semver-2.1.4/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/pubspec_parse-1.2.3/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/pubspec_parse-1.3.0/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/resizable_widget-1.0.5/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/resizable_widget-1.0.5/lib/resizable_widget.dart /Users/leofarias/.pub-cache/hosted/pub.dev/resizable_widget-1.0.5/lib/src/resizable_widget.dart @@ -344,41 +399,41 @@ /Users/leofarias/.pub-cache/hosted/pub.dev/shelf-1.4.1/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/shelf_web_socket-1.0.4/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/source_gen-1.5.0/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.9.1/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib/source_span.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib/src/charcode.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib/src/colors.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib/src/file.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib/src/highlighter.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib/src/location.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib/src/location_mixin.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib/src/span.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib/src/span_exception.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib/src/span_mixin.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib/src/span_with_context.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib/src/utils.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/lib/src/chain.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/lib/src/frame.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/lib/src/lazy_chain.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/lib/src/lazy_trace.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/lib/src/stack_zone_specification.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/lib/src/trace.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/lib/src/unparsed_frame.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/lib/src/utils.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/lib/src/vm_trace.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/lib/stack_trace.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/lib/src/close_guarantee_channel.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/lib/src/delegating_stream_channel.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/lib/src/disconnector.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/lib/src/guarantee_channel.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/lib/src/json_document_transformer.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/lib/src/multi_channel.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/lib/src/stream_channel_completer.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/lib/src/stream_channel_controller.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/lib/src/stream_channel_transformer.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/lib/stream_channel.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.10.0/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib/source_span.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib/src/charcode.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib/src/colors.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib/src/file.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib/src/highlighter.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib/src/location.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib/src/location_mixin.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib/src/span.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib/src/span_exception.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib/src/span_mixin.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib/src/span_with_context.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib/src/utils.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.1/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.1/lib/src/chain.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.1/lib/src/frame.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.1/lib/src/lazy_chain.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.1/lib/src/lazy_trace.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.1/lib/src/stack_zone_specification.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.1/lib/src/trace.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.1/lib/src/unparsed_frame.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.1/lib/src/utils.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.1/lib/src/vm_trace.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stack_trace-1.11.1/lib/stack_trace.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.2/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.2/lib/src/close_guarantee_channel.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.2/lib/src/delegating_stream_channel.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.2/lib/src/disconnector.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.2/lib/src/guarantee_channel.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.2/lib/src/json_document_transformer.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.2/lib/src/multi_channel.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.2/lib/src/stream_channel_completer.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.2/lib/src/stream_channel_controller.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.2/lib/src/stream_channel_transformer.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/stream_channel-2.1.2/lib/stream_channel.dart /Users/leofarias/.pub-cache/hosted/pub.dev/stream_transform-2.1.0/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/string_scanner-1.2.0/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/string_scanner-1.2.0/lib/src/charcode.dart @@ -396,47 +451,44 @@ /Users/leofarias/.pub-cache/hosted/pub.dev/term_glyph-1.2.1/lib/src/generated/top_level.dart /Users/leofarias/.pub-cache/hosted/pub.dev/term_glyph-1.2.1/lib/src/generated/unicode_glyph_set.dart /Users/leofarias/.pub-cache/hosted/pub.dev/term_glyph-1.2.1/lib/term_glyph.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/expect.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/fake.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/hooks.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/scaffolding.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/closed_exception.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/compiler.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/configuration/on_platform.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/configuration/retry.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/configuration/skip.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/configuration/tags.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/configuration/test_on.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/configuration/timeout.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/declarer.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/group.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/group_entry.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/invoker.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/live_test.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/live_test_controller.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/message.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/metadata.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/operating_system.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/platform_selector.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/remote_exception.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/runtime.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/stack_trace_formatter.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/stack_trace_mapper.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/state.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/suite.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/suite_platform.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/test.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/test_failure.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/util/identifier_regex.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/backend/util/pretty_print.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/expect/async_matcher.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/frontend/fake.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/scaffolding/spawn_hybrid.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/scaffolding/test_structure.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/scaffolding/utils.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/src/utils.dart -/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib/test_api.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/fake.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/hooks.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/scaffolding.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/closed_exception.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/compiler.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/configuration/on_platform.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/configuration/retry.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/configuration/skip.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/configuration/tags.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/configuration/test_on.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/configuration/timeout.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/declarer.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/group.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/group_entry.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/invoker.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/live_test.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/live_test_controller.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/message.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/metadata.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/operating_system.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/platform_selector.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/remote_exception.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/runtime.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/stack_trace_formatter.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/stack_trace_mapper.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/state.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/suite.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/suite_platform.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/test.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/test_failure.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/util/identifier_regex.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/backend/util/pretty_print.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/frontend/fake.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/scaffolding/spawn_hybrid.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/scaffolding/test_structure.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/scaffolding/utils.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/test_api-0.6.1/lib/src/utils.dart /Users/leofarias/.pub-cache/hosted/pub.dev/timing-1.0.1/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/typed_data-1.3.2/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/vector_math-2.1.4/LICENSE @@ -465,8 +517,15 @@ /Users/leofarias/.pub-cache/hosted/pub.dev/vector_math-2.1.4/lib/src/vector_math_64/vector3.dart /Users/leofarias/.pub-cache/hosted/pub.dev/vector_math-2.1.4/lib/src/vector_math_64/vector4.dart /Users/leofarias/.pub-cache/hosted/pub.dev/vector_math-2.1.4/lib/vector_math_64.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/vm_service-13.0.0/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/vm_service-13.0.0/lib/src/dart_io_extensions.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/vm_service-13.0.0/lib/src/snapshot_graph.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/vm_service-13.0.0/lib/src/vm_service.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/vm_service-13.0.0/lib/vm_service.dart +/Users/leofarias/.pub-cache/hosted/pub.dev/vm_service-13.0.0/lib/vm_service_io.dart /Users/leofarias/.pub-cache/hosted/pub.dev/watcher-1.1.0/LICENSE -/Users/leofarias/.pub-cache/hosted/pub.dev/web_socket_channel-2.4.0/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/web-0.5.1/LICENSE +/Users/leofarias/.pub-cache/hosted/pub.dev/web_socket_channel-2.4.5/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/widgetbook-3.8.0/LICENSE /Users/leofarias/.pub-cache/hosted/pub.dev/widgetbook-3.8.0/assets/fonts/Poppins/Poppins-Black.ttf /Users/leofarias/.pub-cache/hosted/pub.dev/widgetbook-3.8.0/assets/fonts/Poppins/Poppins-BlackItalic.ttf @@ -667,22 +726,31 @@ /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/color/color_directives.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/color/color_dto.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/color/color_util.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/color/material_colors_util.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/constraints/constraints_dto.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/constraints/constraints_dto.g.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/decoration/decoration_dto.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/decoration/decoration_dto.g.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/decoration/image/decoration_image_dto.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/decoration/image/decoration_image_dto.g.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/enum/enum_util.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/enum/enum_util.g.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/gap/gap_util.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/gap/spacing_side_dto.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/gradient/gradient_dto.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/gradient/gradient_dto.g.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/modifiers/widget_modifiers_data.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/modifiers/widget_modifiers_data_dto.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/modifiers/widget_modifiers_util.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/nested_style/nested_style_attribute.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/nested_style/nested_style_util.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/scalars/scalar_util.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/scalars/scalar_util.g.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/shadow/shadow_dto.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/shadow/shadow_dto.g.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/shadow/shadow_util.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/spacing/edge_insets_dto.dart -/Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/spacing/spacing_dto.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/spacing/edge_insets_dto.g.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/spacing/spacing_util.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/strut_style/strut_style_dto.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/attributes/strut_style/strut_style_dto.g.dart @@ -700,15 +768,19 @@ /Users/leofarias/Projects/mix/packages/mix/lib/src/core/factory/style_mix.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/core/factory/style_widgets_ext.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/core/helpers.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/core/internal/widget_state/gesturable_builder.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/core/internal/widget_state/interactive_widget.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/core/internal/widget_state/widget_state.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/core/modifier.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/core/spec.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/core/styled_widget.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/core/utility.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/core/variant.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/internal/build_context_ext.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/internal/compare_mixin.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/internal/constants.dart -/Users/leofarias/Projects/mix/packages/mix/lib/src/internal/custom_focusable_action_detector.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/internal/deep_collection_equality.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/internal/diagnostic_properties_builder_ext.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/internal/helper_util.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/internal/iterable_ext.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/internal/lerp_helpers.dart @@ -718,11 +790,11 @@ /Users/leofarias/Projects/mix/packages/mix/lib/src/modifiers/clip_widget_modifier.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/modifiers/flexible_widget_modifier.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/modifiers/fractionally_sized_box_widget_modifier.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/modifiers/internal/render_widget_modifier.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/modifiers/intrinsic_widget_modifier.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/modifiers/modifiers.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/modifiers/opacity_widget_modifier.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/modifiers/padding_widget_modifier.dart -/Users/leofarias/Projects/mix/packages/mix/lib/src/modifiers/render_widget_modifier.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/modifiers/rotated_box_widget_modifier.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/modifiers/sized_box_widget_modifier.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/modifiers/transform_widget_modifier.dart @@ -770,669 +842,743 @@ /Users/leofarias/Projects/mix/packages/mix/lib/src/variants/context_variant_util/on_util.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/variants/variant_attribute.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/variants/variants.dart -/Users/leofarias/Projects/mix/packages/mix/lib/src/widgets/pressable/pressable_state.dart -/Users/leofarias/Projects/mix/packages/mix/lib/src/widgets/pressable/pressable_util.dart -/Users/leofarias/Projects/mix/packages/mix/lib/src/widgets/pressable/pressable_widget.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/variants/widget_state_variant.dart +/Users/leofarias/Projects/mix/packages/mix/lib/src/widgets/pressable_widget.dart /Users/leofarias/Projects/mix/packages/mix/lib/src/widgets/widgets.dart /Users/leofarias/Projects/mix/packages/mix_annotations/LICENSE /Users/leofarias/Projects/mix/packages/mix_annotations/lib/mix_annotations.dart /Users/leofarias/Projects/mix/packages/mix_annotations/lib/src/annotations.dart /Users/leofarias/Projects/mix/packages/remix/LICENSE -/Users/leofarias/Projects/mix/packages/remix/demo/lib/components/button.dart +/Users/leofarias/Projects/mix/packages/remix/demo/lib/addons/icon_data_knob.dart +/Users/leofarias/Projects/mix/packages/remix/demo/lib/components/avatar_use_case.dart +/Users/leofarias/Projects/mix/packages/remix/demo/lib/components/button_use_case.dart +/Users/leofarias/Projects/mix/packages/remix/demo/lib/components/callout_use_case.dart +/Users/leofarias/Projects/mix/packages/remix/demo/lib/components/card_use_case.dart +/Users/leofarias/Projects/mix/packages/remix/demo/lib/components/checkbox_use_case.dart +/Users/leofarias/Projects/mix/packages/remix/demo/lib/components/radio_use_case.dart +/Users/leofarias/Projects/mix/packages/remix/demo/lib/components/spinner_use_case.dart +/Users/leofarias/Projects/mix/packages/remix/demo/lib/components/switch_use_case.dart +/Users/leofarias/Projects/mix/packages/remix/demo/lib/helpers/use_case_state.dart /Users/leofarias/Projects/mix/packages/remix/demo/lib/main.dart /Users/leofarias/Projects/mix/packages/remix/demo/lib/main.directories.g.dart /Users/leofarias/Projects/mix/packages/remix/demo/pubspec.yaml -/Users/leofarias/Projects/mix/packages/remix/lib/components/button/button.dart -/Users/leofarias/Projects/mix/packages/remix/lib/components/button/button.style.dart -/Users/leofarias/Projects/mix/packages/remix/lib/components/button/button.variants.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/avatar/avatar_spec.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/avatar/avatar_spec.g.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/avatar/avatar_style.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/avatar/avatar_variants.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/avatar/avatar_widget.dart /Users/leofarias/Projects/mix/packages/remix/lib/components/button/button_spec.dart /Users/leofarias/Projects/mix/packages/remix/lib/components/button/button_spec.g.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/button/button_style.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/button/button_variants.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/button/button_widget.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/callout/callout_spec.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/callout/callout_spec.g.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/callout/callout_style.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/callout/callout_variants.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/callout/callout_widget.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/card/card_spec.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/card/card_spec.g.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/card/card_style.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/card/card_variants.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/card/card_widget.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/checkbox/checkbox_spec.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/checkbox/checkbox_spec.g.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/checkbox/checkbox_style.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/checkbox/checkbox_variants.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/checkbox/checkbox_widget.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/radio/radio_spec.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/radio/radio_spec.g.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/radio/radio_style.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/radio/radio_variants.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/radio/radio_widget.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/spinner/spinner.style.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/spinner/spinner.variants.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/spinner/spinner_painter.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/spinner/spinner_spec.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/spinner/spinner_spec.g.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/spinner/spinner_widget.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/switch/switch_spec.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/switch/switch_spec.g.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/switch/switch_style.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/switch/switch_variants.dart +/Users/leofarias/Projects/mix/packages/remix/lib/components/switch/switch_widget.dart +/Users/leofarias/Projects/mix/packages/remix/lib/helpers/color_palette.dart +/Users/leofarias/Projects/mix/packages/remix/lib/helpers/utility_extension.dart +/Users/leofarias/Projects/mix/packages/remix/lib/helpers/variant.dart /Users/leofarias/Projects/mix/packages/remix/lib/remix.dart -/Users/leofarias/fvm/versions/3.10.6/bin/cache/artifacts/material_fonts/MaterialIcons-Regular.otf -/Users/leofarias/fvm/versions/3.10.6/bin/cache/pkg/sky_engine/LICENSE -/Users/leofarias/fvm/versions/3.10.6/bin/internal/engine.version -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/LICENSE -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/animation.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/cupertino.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/foundation.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/gestures.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/material.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/painting.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/physics.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/rendering.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/scheduler.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/semantics.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/services.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/animation/animation.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/animation/animation_controller.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/animation/animations.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/animation/curves.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/animation/listener_helpers.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/animation/tween.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/animation/tween_sequence.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/activity_indicator.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/adaptive_text_selection_toolbar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/app.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/bottom_tab_bar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/checkbox.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/colors.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/constants.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/context_menu.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/context_menu_action.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/date_picker.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/debug.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/desktop_text_selection.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/desktop_text_selection_toolbar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/desktop_text_selection_toolbar_button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/dialog.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/form_row.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/form_section.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/icon_theme_data.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/icons.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/interface_level.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/list_section.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/list_tile.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/localizations.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/magnifier.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/nav_bar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/page_scaffold.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/picker.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/radio.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/refresh.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/route.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/scrollbar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/search_field.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/segmented_control.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/slider.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/sliding_segmented_control.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/spell_check_suggestions_toolbar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/switch.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/tab_scaffold.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/tab_view.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/text_field.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/text_form_field_row.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/text_selection.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/text_selection_toolbar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/text_selection_toolbar_button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/text_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/thumb_painter.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/cupertino/toggleable.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/_bitfield_io.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/_capabilities_io.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/_isolates_io.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/_platform_io.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/annotations.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/assertions.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/basic_types.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/binding.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/bitfield.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/capabilities.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/change_notifier.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/collections.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/consolidate_response.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/constants.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/debug.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/diagnostics.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/isolates.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/key.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/licenses.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/math.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/memory_allocations.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/node.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/object.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/observer_list.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/persistent_hash_map.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/platform.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/print.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/serialization.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/service_extensions.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/stack_frame.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/synchronous_future.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/foundation/unicode.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/arena.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/binding.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/constants.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/converter.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/debug.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/drag.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/drag_details.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/eager.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/events.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/force_press.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/gesture_settings.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/hit_test.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/long_press.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/lsq_solver.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/monodrag.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/multidrag.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/multitap.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/pointer_router.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/pointer_signal_resolver.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/recognizer.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/resampler.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/scale.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/tap.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/team.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/gestures/velocity_tracker.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/about.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/action_buttons.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/action_chip.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/action_icons_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/adaptive_text_selection_toolbar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/animated_icons.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/animated_icons_data.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/data/add_event.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/data/arrow_menu.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/data/close_menu.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/data/ellipsis_search.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/data/event_add.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/data/home_menu.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/data/list_view.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/data/menu_arrow.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/data/menu_close.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/data/menu_home.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/data/pause_play.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/data/play_pause.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/data/search_ellipsis.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/animated_icons/data/view_list.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/app.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/app_bar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/app_bar_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/arc.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/autocomplete.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/back_button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/badge.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/badge_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/banner.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/banner_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/bottom_app_bar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/bottom_app_bar_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/bottom_navigation_bar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/bottom_navigation_bar_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/bottom_sheet.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/bottom_sheet_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/button_bar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/button_bar_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/button_style.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/button_style_button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/button_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/calendar_date_picker.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/card.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/card_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/checkbox.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/checkbox_list_tile.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/checkbox_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/chip.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/chip_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/choice_chip.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/circle_avatar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/color_scheme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/colors.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/constants.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/curves.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/data_table.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/data_table_source.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/data_table_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/date.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/date_picker.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/date_picker_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/debug.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/desktop_text_selection.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/desktop_text_selection_toolbar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/desktop_text_selection_toolbar_button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/dialog.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/dialog_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/divider.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/divider_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/drawer.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/drawer_header.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/drawer_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/dropdown.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/dropdown_menu.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/dropdown_menu_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/elevated_button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/elevated_button_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/elevation_overlay.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/expand_icon.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/expansion_panel.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/expansion_tile.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/expansion_tile_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/feedback.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/filled_button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/filled_button_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/filter_chip.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/flexible_space_bar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/floating_action_button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/floating_action_button_location.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/floating_action_button_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/flutter_logo.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/grid_tile.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/grid_tile_bar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/icon_button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/icon_button_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/icons.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/ink_decoration.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/ink_highlight.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/ink_ripple.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/ink_sparkle.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/ink_splash.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/ink_well.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/input_border.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/input_chip.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/input_date_picker_form_field.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/input_decorator.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/list_tile.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/list_tile_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/magnifier.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/material.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/material_button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/material_localizations.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/material_state.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/material_state_mixin.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/menu_anchor.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/menu_bar_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/menu_button_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/menu_style.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/menu_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/mergeable_material.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/navigation_bar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/navigation_bar_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/navigation_drawer.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/navigation_drawer_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/navigation_rail.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/navigation_rail_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/no_splash.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/outlined_button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/outlined_button_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/page.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/page_transitions_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/paginated_data_table.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/popup_menu.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/popup_menu_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/progress_indicator.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/progress_indicator_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/radio.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/radio_list_tile.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/radio_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/range_slider.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/refresh_indicator.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/reorderable_list.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/scaffold.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/scrollbar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/scrollbar_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/search.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/search_anchor.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/search_bar_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/search_view_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/segmented_button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/segmented_button_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/selectable_text.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/selection_area.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/shaders/ink_sparkle.frag -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/shadows.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/slider.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/slider_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/snack_bar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/snack_bar_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/spell_check_suggestions_toolbar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/spell_check_suggestions_toolbar_layout_delegate.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/stepper.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/switch.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/switch_list_tile.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/switch_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/tab_bar_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/tab_controller.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/tab_indicator.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/tabs.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/text_button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/text_button_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/text_field.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/text_form_field.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/text_selection.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/text_selection_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/text_selection_toolbar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/text_selection_toolbar_text_button.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/text_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/theme_data.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/time.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/time_picker.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/time_picker_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/toggle_buttons.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/toggle_buttons_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/toggleable.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/tooltip.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/tooltip_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/tooltip_visibility.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/typography.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/material/user_accounts_drawer_header.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/_network_image_io.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/alignment.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/basic_types.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/beveled_rectangle_border.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/binding.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/border_radius.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/borders.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/box_border.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/box_decoration.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/box_fit.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/box_shadow.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/circle_border.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/clip.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/colors.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/continuous_rectangle_border.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/debug.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/decoration.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/decoration_image.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/edge_insets.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/flutter_logo.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/fractional_offset.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/geometry.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/gradient.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/image_cache.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/image_decoder.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/image_provider.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/image_resolution.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/image_stream.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/inline_span.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/linear_border.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/matrix_utils.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/notched_shapes.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/oval_border.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/paint_utilities.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/placeholder_span.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/rounded_rectangle_border.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/shader_warm_up.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/shape_decoration.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/stadium_border.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/star_border.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/strut_style.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/text_painter.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/text_span.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/painting/text_style.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/physics/clamped_simulation.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/physics/friction_simulation.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/physics/gravity_simulation.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/physics/simulation.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/physics/spring_simulation.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/physics/tolerance.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/physics/utils.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/animated_size.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/binding.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/box.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/custom_layout.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/custom_paint.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/debug.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/debug_overflow_indicator.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/editable.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/error.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/flex.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/flow.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/image.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/layer.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/layout_helper.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/list_body.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/list_wheel_viewport.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/mouse_tracker.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/object.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/paragraph.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/performance_overlay.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/platform_view.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/proxy_box.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/proxy_sliver.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/rotated_box.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/selection.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/service_extensions.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/shifted_box.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/sliver.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/sliver_fill.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/sliver_fixed_extent_list.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/sliver_grid.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/sliver_list.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/sliver_padding.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/sliver_persistent_header.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/stack.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/table.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/table_border.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/texture.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/tweens.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/view.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/viewport.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/viewport_offset.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/rendering/wrap.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/scheduler/binding.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/scheduler/debug.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/scheduler/priority.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/scheduler/service_extensions.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/scheduler/ticker.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/semantics/binding.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/semantics/debug.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/semantics/semantics.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/semantics/semantics_event.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/semantics/semantics_service.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/_background_isolate_binary_messenger_io.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/asset_bundle.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/asset_manifest.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/autofill.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/binary_messenger.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/binding.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/browser_context_menu.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/clipboard.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/debug.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/deferred_component.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/font_loader.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/haptic_feedback.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/hardware_keyboard.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/keyboard_inserted_content.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/keyboard_key.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/keyboard_maps.g.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/message_codec.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/message_codecs.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/mouse_cursor.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/mouse_tracking.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/platform_channel.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/platform_views.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/raw_keyboard.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/raw_keyboard_android.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/raw_keyboard_fuchsia.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/raw_keyboard_ios.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/raw_keyboard_linux.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/raw_keyboard_macos.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/raw_keyboard_web.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/raw_keyboard_windows.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/restoration.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/service_extensions.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/spell_check.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/system_channels.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/system_chrome.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/system_navigator.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/system_sound.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/text_boundary.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/text_editing.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/text_editing_delta.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/text_formatter.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/text_input.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/text_layout_metrics.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/services/undo_manager.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/_platform_selectable_region_context_menu_io.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/actions.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/animated_cross_fade.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/animated_scroll_view.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/animated_size.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/animated_switcher.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/annotated_region.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/app.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/async.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/autocomplete.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/autofill.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/automatic_keep_alive.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/banner.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/basic.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/binding.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/bottom_navigation_bar_item.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/color_filter.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/constants.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/container.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/context_menu_button_item.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/context_menu_controller.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/debug.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/default_selection_style.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/default_text_editing_shortcuts.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/desktop_text_selection_toolbar_layout_delegate.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/dismissible.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/display_feature_sub_screen.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/disposable_build_context.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/drag_target.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/dual_transition_builder.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/editable_text.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/fade_in_image.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/focus_manager.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/focus_scope.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/focus_traversal.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/form.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/framework.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/gesture_detector.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/grid_paper.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/heroes.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/icon.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/icon_data.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/icon_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/icon_theme_data.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/image.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/image_filter.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/image_icon.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/implicit_animations.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/inherited_model.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/inherited_notifier.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/inherited_theme.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/interactive_viewer.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/keyboard_listener.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/layout_builder.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/localizations.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/lookup_boundary.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/magnifier.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/media_query.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/modal_barrier.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/navigation_toolbar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/navigator.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/nested_scroll_view.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/notification_listener.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/orientation_builder.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/overflow_bar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/overlay.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/overscroll_indicator.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/page_storage.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/page_view.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/pages.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/performance_overlay.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/placeholder.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/platform_menu_bar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/platform_selectable_region_context_menu.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/platform_view.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/preferred_size.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/primary_scroll_controller.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/raw_keyboard_listener.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/reorderable_list.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/restoration.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/restoration_properties.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/router.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/routes.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/safe_area.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scroll_activity.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scroll_aware_image_provider.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scroll_configuration.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scroll_context.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scroll_controller.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scroll_delegate.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scroll_metrics.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scroll_notification.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scroll_notification_observer.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scroll_physics.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scroll_position.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scroll_simulation.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scroll_view.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scrollable.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scrollable_helpers.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/scrollbar.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/selectable_region.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/selection_container.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/semantics_debugger.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/service_extensions.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/shared_app_data.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/shortcuts.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/single_child_scroll_view.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/size_changed_layout_notifier.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/sliver.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/sliver_fill.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/sliver_layout_builder.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/sliver_persistent_header.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/sliver_prototype_extent_list.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/slotted_render_object_widget.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/snapshot_widget.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/spacer.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/spell_check.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/status_transitions.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/table.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/tap_and_drag_gestures.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/tap_region.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/text.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/text_editing_intents.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/text_selection.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/text_selection_toolbar_anchors.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/text_selection_toolbar_layout_delegate.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/texture.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/ticker_provider.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/title.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/transitions.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/tween_animation_builder.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/undo_history.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/unique_widget.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/value_listenable_builder.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/view.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/viewport.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/visibility.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/widget_inspector.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/widget_span.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/src/widgets/will_pop_scope.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter/lib/widgets.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/flutter_test.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/_binding_io.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/_goldens_io.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/_matchers_io.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/accessibility.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/all_elements.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/animation_sheet.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/binding.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/controller.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/deprecated.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/event_simulation.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/finders.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/frame_timing_summarizer.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/goldens.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/image.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/matchers.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/nonconst.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/platform.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/restoration.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/stack_manipulation.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/test_async_utils.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/test_compat.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/test_default_binary_messenger.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/test_exception_reporter.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/test_pointer.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/test_text_input.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/test_text_input_key_handler.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/test_vsync.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/widget_tester.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_test/lib/src/window.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_tools/lib/src/build_system/targets/common.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_tools/lib/src/build_system/targets/icon_tree_shaker.dart -/Users/leofarias/fvm/versions/3.10.6/packages/flutter_tools/lib/src/build_system/targets/macos.dart +/Users/leofarias/Projects/mix/packages/remix/lib/tokens/color_tokens.dart +/Users/leofarias/Projects/mix/packages/remix/lib/tokens/radius_tokens.dart +/Users/leofarias/Projects/mix/packages/remix/lib/tokens/remix_tokens.dart +/Users/leofarias/Projects/mix/packages/remix/lib/tokens/space_tokens.dart +/Users/leofarias/Projects/mix/packages/remix/lib/tokens/text_style_tokens.dart +/Users/leofarias/fvm/versions/3.19.0/bin/cache/artifacts/material_fonts/MaterialIcons-Regular.otf +/Users/leofarias/fvm/versions/3.19.0/bin/cache/pkg/sky_engine/LICENSE +/Users/leofarias/fvm/versions/3.19.0/bin/internal/engine.version +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/LICENSE +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/animation.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/cupertino.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/foundation.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/gestures.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/material.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/painting.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/physics.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/rendering.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/scheduler.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/semantics.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/services.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/animation/animation.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/animation/animation_controller.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/animation/animation_style.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/animation/animations.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/animation/curves.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/animation/listener_helpers.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/animation/tween.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/animation/tween_sequence.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/activity_indicator.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/adaptive_text_selection_toolbar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/app.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/bottom_tab_bar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/checkbox.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/colors.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/constants.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/context_menu.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/context_menu_action.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/date_picker.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/debug.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/desktop_text_selection.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/desktop_text_selection_toolbar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/desktop_text_selection_toolbar_button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/dialog.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/form_row.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/form_section.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/icon_theme_data.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/icons.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/interface_level.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/list_section.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/list_tile.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/localizations.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/magnifier.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/nav_bar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/page_scaffold.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/picker.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/radio.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/refresh.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/route.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/scrollbar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/search_field.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/segmented_control.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/slider.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/sliding_segmented_control.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/spell_check_suggestions_toolbar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/switch.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/tab_scaffold.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/tab_view.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/text_field.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/text_form_field_row.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/text_selection.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/text_selection_toolbar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/text_selection_toolbar_button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/text_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/thumb_painter.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/cupertino/toggleable.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/_bitfield_io.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/_capabilities_io.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/_isolates_io.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/_platform_io.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/_timeline_io.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/annotations.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/assertions.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/basic_types.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/binding.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/bitfield.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/capabilities.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/change_notifier.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/collections.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/consolidate_response.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/constants.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/debug.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/diagnostics.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/isolates.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/key.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/licenses.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/memory_allocations.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/node.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/object.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/observer_list.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/persistent_hash_map.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/platform.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/print.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/serialization.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/service_extensions.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/stack_frame.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/synchronous_future.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/timeline.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/foundation/unicode.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/arena.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/binding.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/constants.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/converter.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/debug.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/drag.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/drag_details.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/eager.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/events.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/force_press.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/gesture_settings.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/hit_test.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/long_press.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/lsq_solver.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/monodrag.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/multidrag.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/multitap.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/pointer_router.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/pointer_signal_resolver.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/recognizer.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/resampler.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/scale.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/tap.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/tap_and_drag.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/team.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/gestures/velocity_tracker.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/about.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/action_buttons.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/action_chip.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/action_icons_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/adaptive_text_selection_toolbar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/animated_icons.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/animated_icons_data.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/data/add_event.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/data/arrow_menu.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/data/close_menu.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/data/ellipsis_search.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/data/event_add.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/data/home_menu.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/data/list_view.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/data/menu_arrow.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/data/menu_close.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/data/menu_home.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/data/pause_play.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/data/play_pause.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/data/search_ellipsis.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/animated_icons/data/view_list.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/app.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/app_bar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/app_bar_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/arc.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/autocomplete.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/back_button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/badge.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/badge_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/banner.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/banner_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/bottom_app_bar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/bottom_app_bar_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/bottom_navigation_bar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/bottom_navigation_bar_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/bottom_sheet.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/bottom_sheet_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/button_bar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/button_bar_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/button_style.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/button_style_button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/button_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/calendar_date_picker.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/card.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/card_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/checkbox.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/checkbox_list_tile.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/checkbox_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/chip.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/chip_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/choice_chip.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/circle_avatar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/color_scheme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/colors.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/constants.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/curves.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/data_table.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/data_table_source.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/data_table_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/date.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/date_picker.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/date_picker_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/debug.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/desktop_text_selection.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/desktop_text_selection_toolbar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/desktop_text_selection_toolbar_button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/dialog.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/dialog_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/divider.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/divider_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/drawer.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/drawer_header.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/drawer_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/dropdown.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/dropdown_menu.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/dropdown_menu_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/elevated_button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/elevated_button_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/elevation_overlay.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/expand_icon.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/expansion_panel.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/expansion_tile.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/expansion_tile_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/feedback.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/filled_button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/filled_button_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/filter_chip.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/flexible_space_bar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/floating_action_button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/floating_action_button_location.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/floating_action_button_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/flutter_logo.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/grid_tile.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/grid_tile_bar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/icon_button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/icon_button_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/icons.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/ink_decoration.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/ink_highlight.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/ink_ripple.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/ink_sparkle.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/ink_splash.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/ink_well.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/input_border.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/input_chip.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/input_date_picker_form_field.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/input_decorator.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/list_tile.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/list_tile_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/magnifier.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/material.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/material_button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/material_localizations.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/material_state.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/material_state_mixin.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/menu_anchor.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/menu_bar_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/menu_button_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/menu_style.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/menu_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/mergeable_material.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/motion.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/navigation_bar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/navigation_bar_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/navigation_drawer.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/navigation_drawer_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/navigation_rail.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/navigation_rail_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/no_splash.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/outlined_button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/outlined_button_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/page.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/page_transitions_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/paginated_data_table.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/popup_menu.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/popup_menu_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/progress_indicator.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/progress_indicator_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/radio.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/radio_list_tile.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/radio_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/range_slider.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/refresh_indicator.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/reorderable_list.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/scaffold.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/scrollbar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/scrollbar_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/search.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/search_anchor.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/search_bar_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/search_view_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/segmented_button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/segmented_button_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/selectable_text.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/selection_area.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/shaders/ink_sparkle.frag +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/shadows.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/slider.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/slider_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/snack_bar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/snack_bar_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/spell_check_suggestions_toolbar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/spell_check_suggestions_toolbar_layout_delegate.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/stepper.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/switch.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/switch_list_tile.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/switch_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/tab_bar_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/tab_controller.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/tab_indicator.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/tabs.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/text_button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/text_button_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/text_field.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/text_form_field.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/text_selection.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/text_selection_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/text_selection_toolbar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/text_selection_toolbar_text_button.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/text_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/theme_data.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/time.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/time_picker.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/time_picker_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/toggle_buttons.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/toggle_buttons_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/toggleable.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/tooltip.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/tooltip_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/tooltip_visibility.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/typography.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/material/user_accounts_drawer_header.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/_network_image_io.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/alignment.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/basic_types.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/beveled_rectangle_border.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/binding.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/border_radius.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/borders.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/box_border.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/box_decoration.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/box_fit.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/box_shadow.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/circle_border.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/clip.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/colors.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/continuous_rectangle_border.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/debug.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/decoration.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/decoration_image.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/edge_insets.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/flutter_logo.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/fractional_offset.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/geometry.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/gradient.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/image_cache.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/image_decoder.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/image_provider.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/image_resolution.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/image_stream.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/inline_span.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/linear_border.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/matrix_utils.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/notched_shapes.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/oval_border.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/paint_utilities.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/placeholder_span.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/rounded_rectangle_border.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/shader_warm_up.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/shape_decoration.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/stadium_border.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/star_border.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/strut_style.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/text_painter.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/text_scaler.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/text_span.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/painting/text_style.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/physics/clamped_simulation.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/physics/friction_simulation.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/physics/gravity_simulation.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/physics/simulation.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/physics/spring_simulation.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/physics/tolerance.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/physics/utils.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/animated_size.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/binding.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/box.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/custom_layout.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/custom_paint.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/debug.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/debug_overflow_indicator.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/decorated_sliver.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/editable.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/error.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/flex.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/flow.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/image.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/layer.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/layout_helper.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/list_body.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/list_wheel_viewport.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/mouse_tracker.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/object.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/paragraph.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/performance_overlay.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/platform_view.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/proxy_box.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/proxy_sliver.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/rotated_box.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/selection.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/service_extensions.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/shifted_box.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/sliver.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/sliver_fill.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/sliver_fixed_extent_list.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/sliver_grid.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/sliver_group.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/sliver_list.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/sliver_padding.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/sliver_persistent_header.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/stack.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/table.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/table_border.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/texture.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/tweens.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/view.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/viewport.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/viewport_offset.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/rendering/wrap.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/scheduler/binding.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/scheduler/debug.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/scheduler/priority.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/scheduler/service_extensions.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/scheduler/ticker.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/semantics/binding.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/semantics/debug.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/semantics/semantics.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/semantics/semantics_event.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/semantics/semantics_service.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/_background_isolate_binary_messenger_io.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/asset_bundle.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/asset_manifest.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/autofill.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/binary_messenger.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/binding.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/browser_context_menu.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/clipboard.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/debug.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/deferred_component.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/flavor.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/font_loader.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/haptic_feedback.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/hardware_keyboard.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/keyboard_inserted_content.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/keyboard_key.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/keyboard_maps.g.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/live_text.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/message_codec.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/message_codecs.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/mouse_cursor.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/mouse_tracking.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/platform_channel.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/platform_views.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/process_text.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/raw_keyboard.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/raw_keyboard_android.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/raw_keyboard_fuchsia.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/raw_keyboard_ios.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/raw_keyboard_linux.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/raw_keyboard_macos.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/raw_keyboard_web.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/raw_keyboard_windows.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/restoration.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/service_extensions.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/spell_check.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/system_channels.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/system_chrome.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/system_navigator.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/system_sound.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/text_boundary.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/text_editing.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/text_editing_delta.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/text_formatter.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/text_input.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/text_layout_metrics.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/services/undo_manager.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/_html_element_view_io.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/_platform_selectable_region_context_menu_io.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/actions.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/adapter.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/animated_cross_fade.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/animated_scroll_view.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/animated_size.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/animated_switcher.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/annotated_region.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/app.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/app_lifecycle_listener.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/async.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/autocomplete.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/autofill.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/automatic_keep_alive.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/banner.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/basic.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/binding.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/bottom_navigation_bar_item.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/color_filter.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/constants.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/container.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/context_menu_button_item.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/context_menu_controller.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/debug.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/decorated_sliver.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/default_selection_style.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/default_text_editing_shortcuts.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/desktop_text_selection_toolbar_layout_delegate.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/dismissible.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/display_feature_sub_screen.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/disposable_build_context.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/drag_target.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/dual_transition_builder.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/editable_text.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/fade_in_image.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/focus_manager.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/focus_scope.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/focus_traversal.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/form.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/framework.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/gesture_detector.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/grid_paper.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/heroes.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/icon.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/icon_data.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/icon_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/icon_theme_data.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/image.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/image_filter.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/image_icon.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/implicit_animations.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/inherited_model.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/inherited_notifier.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/inherited_theme.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/interactive_viewer.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/keyboard_listener.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/layout_builder.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/localizations.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/lookup_boundary.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/magnifier.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/media_query.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/modal_barrier.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/navigation_toolbar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/navigator.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/navigator_pop_handler.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/nested_scroll_view.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/notification_listener.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/orientation_builder.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/overflow_bar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/overlay.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/overscroll_indicator.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/page_storage.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/page_view.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/pages.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/performance_overlay.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/placeholder.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/platform_menu_bar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/platform_selectable_region_context_menu.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/platform_view.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/pop_scope.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/preferred_size.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/primary_scroll_controller.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/raw_keyboard_listener.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/reorderable_list.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/restoration.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/restoration_properties.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/router.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/routes.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/safe_area.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scroll_activity.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scroll_aware_image_provider.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scroll_configuration.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scroll_context.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scroll_controller.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scroll_delegate.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scroll_metrics.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scroll_notification.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scroll_notification_observer.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scroll_physics.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scroll_position.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scroll_simulation.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scroll_view.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scrollable.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scrollable_helpers.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/scrollbar.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/selectable_region.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/selection_container.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/semantics_debugger.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/service_extensions.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/shared_app_data.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/shortcuts.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/single_child_scroll_view.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/size_changed_layout_notifier.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/sliver.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/sliver_fill.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/sliver_layout_builder.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/sliver_persistent_header.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/sliver_prototype_extent_list.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/sliver_varied_extent_list.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/slotted_render_object_widget.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/snapshot_widget.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/spacer.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/spell_check.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/status_transitions.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/table.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/tap_region.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/text.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/text_editing_intents.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/text_selection.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/text_selection_toolbar_anchors.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/text_selection_toolbar_layout_delegate.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/texture.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/ticker_provider.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/title.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/transitions.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/tween_animation_builder.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/two_dimensional_scroll_view.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/two_dimensional_viewport.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/undo_history.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/unique_widget.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/value_listenable_builder.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/view.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/viewport.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/visibility.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/widget_inspector.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/widget_span.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/src/widgets/will_pop_scope.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter/lib/widgets.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/flutter_test.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/_binding_io.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/_goldens_io.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/_matchers_io.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/accessibility.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/animation_sheet.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/binding.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/controller.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/deprecated.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/event_simulation.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/finders.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/frame_timing_summarizer.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/goldens.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/image.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/matchers.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/mock_canvas.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/mock_event_channel.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/nonconst.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/platform.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/recording_canvas.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/restoration.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/stack_manipulation.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/test_async_utils.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/test_compat.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/test_default_binary_messenger.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/test_exception_reporter.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/test_pointer.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/test_text_input.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/test_text_input_key_handler.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/test_vsync.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/tree_traversal.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/widget_tester.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_test/lib/src/window.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_tools/lib/src/build_system/targets/common.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_tools/lib/src/build_system/targets/icon_tree_shaker.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_tools/lib/src/build_system/targets/macos.dart +/Users/leofarias/fvm/versions/3.19.0/packages/flutter_tools/lib/src/build_system/targets/native_assets.dart diff --git a/packages/remix/demo/macos/Flutter/ephemeral/flutter_export_environment.sh b/packages/remix/demo/macos/Flutter/ephemeral/flutter_export_environment.sh new file mode 100755 index 000000000..f550ea72f --- /dev/null +++ b/packages/remix/demo/macos/Flutter/ephemeral/flutter_export_environment.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# This is a generated file; do not edit or check into version control. +export "FLUTTER_ROOT=/Users/leofarias/fvm/versions/3.19.0" +export "FLUTTER_APPLICATION_PATH=/Users/leofarias/Projects/mix/packages/remix/demo" +export "COCOAPODS_PARALLEL_CODE_SIGN=true" +export "FLUTTER_TARGET=/Users/leofarias/Projects/mix/packages/remix/demo/lib/main.dart" +export "FLUTTER_BUILD_DIR=build" +export "FLUTTER_BUILD_NAME=1.0.0" +export "FLUTTER_BUILD_NUMBER=1" +export "DART_DEFINES=RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==,RkxVVFRFUl9XRUJfQ0FOVkFTS0lUX1VSTD1odHRwczovL3d3dy5nc3RhdGljLmNvbS9mbHV0dGVyLWNhbnZhc2tpdC8wNDgxN2M5OWM5ZmQ0OTU2ZjI3NTA1MjA0ZjdlMzQ0MzM1ODEwYWVkLw==" +export "DART_OBFUSCATION=false" +export "TRACK_WIDGET_CREATION=true" +export "TREE_SHAKE_ICONS=false" +export "PACKAGE_CONFIG=/Users/leofarias/Projects/mix/packages/remix/demo/.dart_tool/package_config.json" diff --git a/packages/remix/demo/macos/Runner.xcodeproj/project.pbxproj b/packages/remix/demo/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000..5da3a824e --- /dev/null +++ b/packages/remix/demo/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,695 @@ +// !$*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 */; }; +/* 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 */ + 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 = ""; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "demo.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 331C80D2294CF70F00263BE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C80D6294CF71000263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C80D7294CF71000263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 331C80D6294CF71000263BE5 /* RunnerTests */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* demo.app */, + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C80D4294CF70F00263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 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 = ( + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* demo.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1510; + 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"; + }; +/* 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 = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 331C80DB294CF71000263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.demo.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/demo.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/demo"; + }; + name = Debug; + }; + 331C80DC294CF71000263BE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.demo.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/demo.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/demo"; + }; + name = Release; + }; + 331C80DD294CF71000263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.demo.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/demo.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/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 */; +} diff --git a/packages/remix/demo/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/remix/demo/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/packages/remix/demo/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/remix/demo/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/remix/demo/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000..ae8764fa2 --- /dev/null +++ b/packages/remix/demo/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/remix/demo/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/remix/demo/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..1d526a16e --- /dev/null +++ b/packages/remix/demo/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/remix/demo/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/remix/demo/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/packages/remix/demo/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/remix/demo/macos/Runner/AppDelegate.swift b/packages/remix/demo/macos/Runner/AppDelegate.swift new file mode 100644 index 000000000..d53ef6437 --- /dev/null +++ b/packages/remix/demo/macos/Runner/AppDelegate.swift @@ -0,0 +1,9 @@ +import Cocoa +import FlutterMacOS + +@NSApplicationMain +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..a2ec33f19 --- /dev/null +++ b/packages/remix/demo/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" + } +} diff --git a/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 000000000..82b6f9d9a Binary files /dev/null and b/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 000000000..13b35eba5 Binary files /dev/null and b/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 000000000..0a3f5fa40 Binary files /dev/null and b/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 000000000..bdb57226d Binary files /dev/null and b/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 000000000..f083318e0 Binary files /dev/null and b/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 000000000..326c0e72c Binary files /dev/null and b/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 000000000..2f1632cfd Binary files /dev/null and b/packages/remix/demo/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/packages/remix/demo/macos/Runner/Base.lproj/MainMenu.xib b/packages/remix/demo/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 000000000..80e867a4e --- /dev/null +++ b/packages/remix/demo/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/remix/demo/macos/Runner/Configs/AppInfo.xcconfig b/packages/remix/demo/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 000000000..0899fc39f --- /dev/null +++ b/packages/remix/demo/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 = demo + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = com.example.demo + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2024 com.example. All rights reserved. diff --git a/packages/remix/demo/macos/Runner/Configs/Debug.xcconfig b/packages/remix/demo/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 000000000..36b0fd946 --- /dev/null +++ b/packages/remix/demo/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/packages/remix/demo/macos/Runner/Configs/Release.xcconfig b/packages/remix/demo/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 000000000..dff4f4956 --- /dev/null +++ b/packages/remix/demo/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/packages/remix/demo/macos/Runner/Configs/Warnings.xcconfig b/packages/remix/demo/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 000000000..42bcbf478 --- /dev/null +++ b/packages/remix/demo/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 diff --git a/packages/remix/demo/macos/Runner/DebugProfile.entitlements b/packages/remix/demo/macos/Runner/DebugProfile.entitlements new file mode 100644 index 000000000..4ec85ba67 --- /dev/null +++ b/packages/remix/demo/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.network.client + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/packages/remix/demo/macos/Runner/Info.plist b/packages/remix/demo/macos/Runner/Info.plist new file mode 100644 index 000000000..4789daa6a --- /dev/null +++ b/packages/remix/demo/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/packages/remix/demo/macos/Runner/MainFlutterWindow.swift b/packages/remix/demo/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 000000000..3cc05eb23 --- /dev/null +++ b/packages/remix/demo/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/packages/remix/demo/macos/Runner/Release.entitlements b/packages/remix/demo/macos/Runner/Release.entitlements new file mode 100644 index 000000000..08ba3a3fa --- /dev/null +++ b/packages/remix/demo/macos/Runner/Release.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.network.client + + + diff --git a/packages/remix/demo/macos/RunnerTests/RunnerTests.swift b/packages/remix/demo/macos/RunnerTests/RunnerTests.swift new file mode 100644 index 000000000..5418c9f53 --- /dev/null +++ b/packages/remix/demo/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. + } + +} diff --git a/packages/remix/demo/pubspec.yaml b/packages/remix/demo/pubspec.yaml new file mode 100644 index 000000000..0756b1bc7 --- /dev/null +++ b/packages/remix/demo/pubspec.yaml @@ -0,0 +1,32 @@ +name: demo +description: "A new Flutter project." + +publish_to: "none" + +version: 1.0.0+1 + +environment: + sdk: ">=3.3.0 <4.0.0" + +dependencies: + flutter: + sdk: flutter + + cupertino_icons: ^1.0.2 + widgetbook_annotation: ^3.1.0 + widgetbook: ^3.8.0 + remix: + path: ../ + + mix: ^1.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + flutter_lints: ^2.0.0 + widgetbook_generator: ^3.8.0 + build_runner: ^2.4.8 + +flutter: + uses-material-design: true diff --git a/packages/remix/demo/test/widget_test.dart b/packages/remix/demo/test/widget_test.dart new file mode 100644 index 000000000..ae72ec40c --- /dev/null +++ b/packages/remix/demo/test/widget_test.dart @@ -0,0 +1,25 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +void main() { + // testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // // Build our app and trigger a frame. + // await tester.pumpWidget(const HotReload()); + + // // Verify that our counter starts at 0. + // expect(find.text('0'), findsOneWidget); + // expect(find.text('1'), findsNothing); + + // // Tap the '+' icon and trigger a frame. + // await tester.tap(find.byIcon(Icons.add)); + // await tester.pump(); + + // // Verify that our counter has incremented. + // expect(find.text('0'), findsNothing); + // expect(find.text('1'), findsOneWidget); + // }); +} diff --git a/packages/remix/demo/web/favicon.png b/packages/remix/demo/web/favicon.png new file mode 100644 index 000000000..8aaa46ac1 Binary files /dev/null and b/packages/remix/demo/web/favicon.png differ diff --git a/packages/remix/demo/web/icons/Icon-192.png b/packages/remix/demo/web/icons/Icon-192.png new file mode 100644 index 000000000..b749bfef0 Binary files /dev/null and b/packages/remix/demo/web/icons/Icon-192.png differ diff --git a/packages/remix/demo/web/icons/Icon-512.png b/packages/remix/demo/web/icons/Icon-512.png new file mode 100644 index 000000000..88cfd48df Binary files /dev/null and b/packages/remix/demo/web/icons/Icon-512.png differ diff --git a/packages/remix/demo/web/icons/Icon-maskable-192.png b/packages/remix/demo/web/icons/Icon-maskable-192.png new file mode 100644 index 000000000..eb9b4d76e Binary files /dev/null and b/packages/remix/demo/web/icons/Icon-maskable-192.png differ diff --git a/packages/remix/demo/web/icons/Icon-maskable-512.png b/packages/remix/demo/web/icons/Icon-maskable-512.png new file mode 100644 index 000000000..d69c56691 Binary files /dev/null and b/packages/remix/demo/web/icons/Icon-maskable-512.png differ diff --git a/packages/remix/demo/web/index.html b/packages/remix/demo/web/index.html new file mode 100644 index 000000000..1a98da7dd --- /dev/null +++ b/packages/remix/demo/web/index.html @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + demo + + + + + + + + + + diff --git a/packages/remix/demo/web/manifest.json b/packages/remix/demo/web/manifest.json new file mode 100644 index 000000000..238a284b9 --- /dev/null +++ b/packages/remix/demo/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "demo", + "short_name": "demo", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/packages/remix/demo/windows/.gitignore b/packages/remix/demo/windows/.gitignore new file mode 100644 index 000000000..d492d0d98 --- /dev/null +++ b/packages/remix/demo/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ephemeral/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/packages/remix/demo/windows/CMakeLists.txt b/packages/remix/demo/windows/CMakeLists.txt new file mode 100644 index 000000000..15d0aae2b --- /dev/null +++ b/packages/remix/demo/windows/CMakeLists.txt @@ -0,0 +1,102 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.14) +project(demo LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "demo") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(SET CMP0063 NEW) + +# Define build configuration option. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() +# Define settings for the Profile build mode. +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build; see runner/CMakeLists.txt. +add_subdirectory("runner") + + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/packages/remix/demo/windows/flutter/CMakeLists.txt b/packages/remix/demo/windows/flutter/CMakeLists.txt new file mode 100644 index 000000000..930d2071a --- /dev/null +++ b/packages/remix/demo/windows/flutter/CMakeLists.txt @@ -0,0 +1,104 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.14) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + windows-x64 $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/packages/remix/demo/windows/flutter/generated_plugin_registrant.cc b/packages/remix/demo/windows/flutter/generated_plugin_registrant.cc new file mode 100644 index 000000000..8b6d4680a --- /dev/null +++ b/packages/remix/demo/windows/flutter/generated_plugin_registrant.cc @@ -0,0 +1,11 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + + +void RegisterPlugins(flutter::PluginRegistry* registry) { +} diff --git a/packages/remix/demo/windows/flutter/generated_plugin_registrant.h b/packages/remix/demo/windows/flutter/generated_plugin_registrant.h new file mode 100644 index 000000000..dc139d85a --- /dev/null +++ b/packages/remix/demo/windows/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/packages/remix/demo/windows/flutter/generated_plugins.cmake b/packages/remix/demo/windows/flutter/generated_plugins.cmake new file mode 100644 index 000000000..b93c4c30c --- /dev/null +++ b/packages/remix/demo/windows/flutter/generated_plugins.cmake @@ -0,0 +1,23 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/packages/remix/demo/windows/runner/CMakeLists.txt b/packages/remix/demo/windows/runner/CMakeLists.txt new file mode 100644 index 000000000..394917c05 --- /dev/null +++ b/packages/remix/demo/windows/runner/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.14) +project(runner LANGUAGES CXX) + +# Define the application target. To change its name, change BINARY_NAME in the +# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer +# work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add preprocessor definitions for the build version. +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") + +# Disable Windows macros that collide with C++ standard library functions. +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") + +# Add dependency libraries and include directories. Add any application-specific +# dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/packages/remix/demo/windows/runner/Runner.rc b/packages/remix/demo/windows/runner/Runner.rc new file mode 100644 index 000000000..c15129e40 --- /dev/null +++ b/packages/remix/demo/windows/runner/Runner.rc @@ -0,0 +1,121 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) +#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD +#else +#define VERSION_AS_NUMBER 1,0,0,0 +#endif + +#if defined(FLUTTER_VERSION) +#define VERSION_AS_STRING FLUTTER_VERSION +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "com.example" "\0" + VALUE "FileDescription", "demo" "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "demo" "\0" + VALUE "LegalCopyright", "Copyright (C) 2024 com.example. All rights reserved." "\0" + VALUE "OriginalFilename", "demo.exe" "\0" + VALUE "ProductName", "demo" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/packages/remix/demo/windows/runner/flutter_window.cpp b/packages/remix/demo/windows/runner/flutter_window.cpp new file mode 100644 index 000000000..b25e363ef --- /dev/null +++ b/packages/remix/demo/windows/runner/flutter_window.cpp @@ -0,0 +1,66 @@ +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject& project) + : project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + + flutter_controller_->engine()->SetNextFrameCallback([&]() { + this->Show(); + }); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opportunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} diff --git a/packages/remix/demo/windows/runner/flutter_window.h b/packages/remix/demo/windows/runner/flutter_window.h new file mode 100644 index 000000000..6da0652f0 --- /dev/null +++ b/packages/remix/demo/windows/runner/flutter_window.h @@ -0,0 +1,33 @@ +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow hosting a Flutter view running |project|. + explicit FlutterWindow(const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/packages/remix/demo/windows/runner/main.cpp b/packages/remix/demo/windows/runner/main.cpp new file mode 100644 index 000000000..fec4dbaa0 --- /dev/null +++ b/packages/remix/demo/windows/runner/main.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "flutter_window.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = + GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.Create(L"demo", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + ::MSG msg; + while (::GetMessage(&msg, nullptr, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + ::CoUninitialize(); + return EXIT_SUCCESS; +} diff --git a/packages/remix/demo/windows/runner/resource.h b/packages/remix/demo/windows/runner/resource.h new file mode 100644 index 000000000..66a65d1e4 --- /dev/null +++ b/packages/remix/demo/windows/runner/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/packages/remix/demo/windows/runner/resources/app_icon.ico b/packages/remix/demo/windows/runner/resources/app_icon.ico new file mode 100644 index 000000000..c04e20caf Binary files /dev/null and b/packages/remix/demo/windows/runner/resources/app_icon.ico differ diff --git a/packages/remix/demo/windows/runner/runner.exe.manifest b/packages/remix/demo/windows/runner/runner.exe.manifest new file mode 100644 index 000000000..a42ea7687 --- /dev/null +++ b/packages/remix/demo/windows/runner/runner.exe.manifest @@ -0,0 +1,20 @@ + + + + + PerMonitorV2 + + + + + + + + + + + + + + + diff --git a/packages/remix/demo/windows/runner/utils.cpp b/packages/remix/demo/windows/runner/utils.cpp new file mode 100644 index 000000000..b2b08734d --- /dev/null +++ b/packages/remix/demo/windows/runner/utils.cpp @@ -0,0 +1,65 @@ +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr) + -1; // remove the trailing null character + int input_length = (int)wcslen(utf16_string); + std::string utf8_string; + if (target_length <= 0 || target_length > utf8_string.max_size()) { + return utf8_string; + } + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + input_length, utf8_string.data(), target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} diff --git a/packages/remix/demo/windows/runner/utils.h b/packages/remix/demo/windows/runner/utils.h new file mode 100644 index 000000000..3879d5475 --- /dev/null +++ b/packages/remix/demo/windows/runner/utils.h @@ -0,0 +1,19 @@ +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ diff --git a/packages/remix/demo/windows/runner/win32_window.cpp b/packages/remix/demo/windows/runner/win32_window.cpp new file mode 100644 index 000000000..60608d0fe --- /dev/null +++ b/packages/remix/demo/windows/runner/win32_window.cpp @@ -0,0 +1,288 @@ +#include "win32_window.h" + +#include +#include + +#include "resource.h" + +namespace { + +/// Window attribute that enables dark mode window decorations. +/// +/// Redefined in case the developer's machine has a Windows SDK older than +/// version 10.0.22000.0. +/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute +#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +#endif + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +/// Registry key for app theme preference. +/// +/// A value of 0 indicates apps should use dark mode. A non-zero or missing +/// value indicates apps should use light mode. +constexpr const wchar_t kGetPreferredBrightnessRegKey[] = + L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; +constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + } + FreeLibrary(user32_module); +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registrar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::Create(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + UpdateTheme(window); + + return OnCreate(); +} + +bool Win32Window::Show() { + return ShowWindow(window_handle_, SW_SHOWNORMAL); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + + case WM_DWMCOLORIZATIONCOLORCHANGED: + UpdateTheme(hwnd); + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} + +void Win32Window::UpdateTheme(HWND const window) { + DWORD light_mode; + DWORD light_mode_size = sizeof(light_mode); + LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, + kGetPreferredBrightnessRegValue, + RRF_RT_REG_DWORD, nullptr, &light_mode, + &light_mode_size); + + if (result == ERROR_SUCCESS) { + BOOL enable_dark_mode = light_mode == 0; + DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, + &enable_dark_mode, sizeof(enable_dark_mode)); + } +} diff --git a/packages/remix/demo/windows/runner/win32_window.h b/packages/remix/demo/windows/runner/win32_window.h new file mode 100644 index 000000000..e901dde68 --- /dev/null +++ b/packages/remix/demo/windows/runner/win32_window.h @@ -0,0 +1,102 @@ +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates a win32 window with |title| that is positioned and sized using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size this function will scale the inputted width and height as + // as appropriate for the default monitor. The window is invisible until + // |Show| is called. Returns true if the window was created successfully. + bool Create(const std::wstring& title, const Point& origin, const Size& size); + + // Show the current window. Returns true if the window was successfully shown. + bool Show(); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + // Update the window frame's theme to match the system theme. + static void UpdateTheme(HWND const window); + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_ diff --git a/packages/remix/lib/components/avatar/avatar_spec.dart b/packages/remix/lib/components/avatar/avatar_spec.dart new file mode 100644 index 000000000..24922f58f --- /dev/null +++ b/packages/remix/lib/components/avatar/avatar_spec.dart @@ -0,0 +1,26 @@ +import 'package:flutter/widgets.dart'; +import 'package:mix/mix.dart'; +import 'package:mix_annotations/mix_annotations.dart'; + +part 'avatar_spec.g.dart'; + +@MixableSpec() +base class AvatarSpec extends Spec with _$AvatarSpec { + final BoxSpec container; + final ImageSpec image; + final TextSpec fallback; + + /// {@macro avatar_spec_of} + static const of = _$AvatarSpec.of; + + static const from = _$AvatarSpec.from; + + const AvatarSpec({ + BoxSpec? container, + ImageSpec? image, + TextSpec? fallback, + super.animated, + }) : container = container ?? const BoxSpec(), + image = image ?? const ImageSpec(), + fallback = fallback ?? const TextSpec(); +} diff --git a/packages/remix/lib/components/avatar/avatar_spec.g.dart b/packages/remix/lib/components/avatar/avatar_spec.g.dart new file mode 100644 index 000000000..ed5e99c57 --- /dev/null +++ b/packages/remix/lib/components/avatar/avatar_spec.g.dart @@ -0,0 +1,225 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'avatar_spec.dart'; + +// ************************************************************************** +// MixableSpecGenerator +// ************************************************************************** + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$AvatarSpec on Spec { + static AvatarSpec from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? + const AvatarSpec(); + } + + /// {@template avatar_spec_of} + /// Retrieves the [AvatarSpec] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [AvatarSpec] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [AvatarSpec]. + /// + /// Example: + /// + /// ```dart + /// final avatarSpec = AvatarSpec.of(context); + /// ``` + /// {@endtemplate} + static AvatarSpec of(BuildContext context) { + return _$AvatarSpec.from(Mix.of(context)); + } + + /// Creates a copy of this [AvatarSpec] but with the given fields + /// replaced with the new values. + @override + AvatarSpec copyWith({ + BoxSpec? container, + ImageSpec? image, + TextSpec? fallback, + AnimatedData? animated, + }) { + return AvatarSpec( + container: container ?? _$this.container, + image: image ?? _$this.image, + fallback: fallback ?? _$this.fallback, + animated: animated ?? _$this.animated, + ); + } + + /// Linearly interpolates between this [AvatarSpec] and another [AvatarSpec] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [AvatarSpec] is returned. When [t] is 1.0, the [other] [AvatarSpec] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [AvatarSpec] is returned. + /// + /// If [other] is null, this method returns the current [AvatarSpec] instance. + /// + /// The interpolation is performed on each property of the [AvatarSpec] using the appropriate + /// interpolation method: + /// + /// - [BoxSpec.lerp] for [container]. + /// - [ImageSpec.lerp] for [image]. + /// - [TextSpec.lerp] for [fallback]. + + /// For [animated], the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [AvatarSpec] is used. Otherwise, the value + /// from the [other] [AvatarSpec] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [AvatarSpec] configurations. + @override + AvatarSpec lerp(AvatarSpec? other, double t) { + if (other == null) return _$this; + + return AvatarSpec( + container: _$this.container.lerp(other.container, t), + image: _$this.image.lerp(other.image, t), + fallback: _$this.fallback.lerp(other.fallback, t), + animated: t < 0.5 ? _$this.animated : other.animated, + ); + } + + /// The list of properties that constitute the state of this [AvatarSpec]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [AvatarSpec] instances for equality. + @override + List get props => [ + _$this.container, + _$this.image, + _$this.fallback, + _$this.animated, + ]; + + AvatarSpec get _$this => this as AvatarSpec; +} + +/// Represents the attributes of a [AvatarSpec]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [AvatarSpec]. +/// +/// Use this class to configure the attributes of a [AvatarSpec] and pass it to +/// the [AvatarSpec] constructor. +final class AvatarSpecAttribute extends SpecAttribute { + final BoxSpecAttribute? container; + final ImageSpecAttribute? image; + final TextSpecAttribute? fallback; + + const AvatarSpecAttribute({ + this.container, + this.image, + this.fallback, + super.animated, + }); + + /// Resolves to [AvatarSpec] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final avatarSpec = AvatarSpecAttribute(...).resolve(mix); + /// ``` + @override + AvatarSpec resolve(MixData mix) { + return AvatarSpec( + container: container?.resolve(mix), + image: image?.resolve(mix), + fallback: fallback?.resolve(mix), + animated: animated?.resolve(mix) ?? mix.animation, + ); + } + + /// Merges the properties of this [AvatarSpecAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [AvatarSpecAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + AvatarSpecAttribute merge(covariant AvatarSpecAttribute? other) { + if (other == null) return this; + + return AvatarSpecAttribute( + container: container?.merge(other.container) ?? other.container, + image: image?.merge(other.image) ?? other.image, + fallback: fallback?.merge(other.fallback) ?? other.fallback, + animated: animated?.merge(other.animated) ?? other.animated, + ); + } + + /// The list of properties that constitute the state of this [AvatarSpecAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [AvatarSpecAttribute] instances for equality. + @override + List get props => [ + container, + image, + fallback, + animated, + ]; +} + +/// Utility class for configuring [AvatarSpecAttribute] properties. +/// +/// This class provides methods to set individual properties of a [AvatarSpecAttribute]. +/// Use the methods of this class to configure specific properties of a [AvatarSpecAttribute]. +base class AvatarSpecUtility + extends SpecUtility { + /// Utility for defining [AvatarSpecAttribute.container] + late final container = BoxSpecUtility((v) => only(container: v)); + + /// Utility for defining [AvatarSpecAttribute.image] + late final image = ImageSpecUtility((v) => only(image: v)); + + /// Utility for defining [AvatarSpecAttribute.fallback] + late final fallback = TextSpecUtility((v) => only(fallback: v)); + + /// Utility for defining [AvatarSpecAttribute.animated] + late final animated = AnimatedUtility((v) => only(animated: v)); + + AvatarSpecUtility(super.builder); + + static final self = AvatarSpecUtility((v) => v); + + /// Returns a new [AvatarSpecAttribute] with the specified properties. + @override + T only({ + BoxSpecAttribute? container, + ImageSpecAttribute? image, + TextSpecAttribute? fallback, + AnimatedDataDto? animated, + }) { + return builder(AvatarSpecAttribute( + container: container, + image: image, + fallback: fallback, + animated: animated, + )); + } +} + +/// A tween that interpolates between two [AvatarSpec] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [AvatarSpec] specifications. +class AvatarSpecTween extends Tween { + AvatarSpecTween({ + super.begin, + super.end, + }); + + @override + AvatarSpec lerp(double t) { + if (begin == null && end == null) return const AvatarSpec(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} diff --git a/packages/remix/lib/components/avatar/avatar_style.dart b/packages/remix/lib/components/avatar/avatar_style.dart new file mode 100644 index 000000000..cbb6fcb90 --- /dev/null +++ b/packages/remix/lib/components/avatar/avatar_style.dart @@ -0,0 +1,104 @@ +// ignore_for_file: camel_case_types + +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/avatar/avatar_spec.dart'; +import 'package:remix/components/avatar/avatar_variants.dart'; +import 'package:remix/helpers/utility_extension.dart'; +import 'package:remix/tokens/remix_tokens.dart'; + +final _avatar = AvatarSpecUtility.self; +final _container = _avatar.container; +final _image = _avatar.image; +final _fallback = _avatar.fallback; +Style get _baseStyle => Style( + _container.borderRadius(99), + _image.fit.cover(), + _container.alignment.center(), + _fallback.textAlign.center(), + _fallback.style.fontWeight(FontWeight.bold), + _fallback.style.color.ref($rx.color.neutral(1)), + ); + +Style get _solidVariant => Style( + _container.color.ref($rx.color.accent()), + ); + +Style get _softVariant => Style( + _container.color.ref($rx.color.accent(4)), + ); + +Style get _size1 => Style( + _container.size(16), + _fallback.style.fontSize(10), + ); + +Style get _size2 => Style( + _container.size(20), + _fallback.style.fontSize(12), + ); + +Style get _size3 => Style( + _container.size(24), + _fallback.style.fontSize(14), + ); + +Style get _size4 => Style( + _container.size(32), + _fallback.style.fontSize(16), + ); + +Style get _size5 => Style( + _container.size(40), + _fallback.style.fontSize(20), + ); + +Style get _size6 => Style( + _container.size(48), + _fallback.style.fontSize(24), + ); + +Style get _size7 => Style( + _container.size(56), + _fallback.style.fontSize(28), + ); + +Style get _size8 => Style( + _container.size(64), + _fallback.style.fontSize(32), + ); + +Style get _radiusNone => + Style($with.clipRRect(borderRadius: BorderRadius.zero)); +Style get _radiusSmall => + Style($with.clipRRect(borderRadius: BorderRadius.circular(4))); +Style get _radiusMedium => + Style($with.clipRRect(borderRadius: BorderRadius.circular(8))); +Style get _radiusLarge => + Style($with.clipRRect(borderRadius: BorderRadius.circular(12))); +Style get _radiusFull => Style($with.clipOval()); + +Style avatarStyle(Style? style, List variants) { + return Style( + _baseStyle(), + AvatarVariant.solid(_solidVariant()), + AvatarVariant.soft(_softVariant()), + + // Sizes + AvatarSize.size1(_size1()), + AvatarSize.size2(_size2()), + AvatarSize.size3(_size3()), + AvatarSize.size4(_size4()), + AvatarSize.size5(_size5()), + AvatarSize.size6(_size6()), + AvatarSize.size7(_size7()), + AvatarSize.size8(_size8()), + + // Radius + AvatarRadius.none(_radiusNone()), + AvatarRadius.small(_radiusSmall()), + AvatarRadius.medium(_radiusMedium()), + AvatarRadius.large(_radiusLarge()), + AvatarRadius.full(_radiusFull()), + ).merge(style).applyVariants(variants); +} diff --git a/packages/remix/lib/components/avatar/avatar_variants.dart b/packages/remix/lib/components/avatar/avatar_variants.dart new file mode 100644 index 000000000..04c79efbe --- /dev/null +++ b/packages/remix/lib/components/avatar/avatar_variants.dart @@ -0,0 +1,50 @@ +import 'package:remix/helpers/variant.dart'; + +abstract interface class IAvatarVariant extends RemixVariant { + const IAvatarVariant(String name) : super('avatar.$name'); +} + +class AvatarVariant extends IAvatarVariant { + const AvatarVariant(String name) : super('variant.$name'); + + static const solid = AvatarVariant('solid'); + static const soft = AvatarVariant('soft'); + + static List get values => [solid, soft]; +} + +class AvatarSize extends IAvatarVariant { + const AvatarSize(String name) : super('size.$name'); + + static const size1 = AvatarSize('size1'); + static const size2 = AvatarSize('size2'); + static const size3 = AvatarSize('size3'); + static const size4 = AvatarSize('size4'); + static const size5 = AvatarSize('size5'); + static const size6 = AvatarSize('size6'); + static const size7 = AvatarSize('size7'); + static const size8 = AvatarSize('size8'); + + static List get values => [ + size1, + size2, + size3, + size4, + size5, + size6, + size7, + size8, + ]; +} + +class AvatarRadius extends IAvatarVariant { + const AvatarRadius(String name) : super('radius.$name'); + + static const none = AvatarRadius('none'); + static const small = AvatarRadius('small'); + static const medium = AvatarRadius('medium'); + static const large = AvatarRadius('large'); + static const full = AvatarRadius('full'); + + static List get values => [none, small, medium, large, full]; +} diff --git a/packages/remix/lib/components/avatar/avatar_widget.dart b/packages/remix/lib/components/avatar/avatar_widget.dart new file mode 100644 index 000000000..14eb51503 --- /dev/null +++ b/packages/remix/lib/components/avatar/avatar_widget.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/avatar/avatar_spec.dart'; +import 'package:remix/components/avatar/avatar_style.dart'; +import 'package:remix/components/avatar/avatar_variants.dart'; + +class RxAvatar extends StatelessWidget { + const RxAvatar({ + super.key, + this.image, + this.fallback, + this.size = AvatarSize.size4, + this.variant = AvatarVariant.solid, + this.radius = AvatarRadius.full, + this.style, + }); + + final ImageProvider? image; + final String? fallback; + final AvatarSize size; + final AvatarVariant variant; + final AvatarRadius radius; + final Style? style; + + @override + Widget build(BuildContext context) { + return SpecBuilder( + style: avatarStyle(style, [size, variant, radius]), + builder: (context) { + final spec = AvatarSpec.of(context); + + final ContainerWidget = spec.container; + final ImageWidget = spec.image; + final FallbackWidget = spec.fallback; + + return ContainerWidget( + child: image != null + ? ImageWidget( + image: image!, + errorBuilder: (context, error, stackTrace) { + return FallbackWidget(fallback ?? ''); + }, + ) + : FallbackWidget(fallback ?? ''), + ); + }, + ); + } +} diff --git a/packages/remix/lib/components/badge/badge_spec.dart b/packages/remix/lib/components/badge/badge_spec.dart new file mode 100644 index 000000000..5992f9752 --- /dev/null +++ b/packages/remix/lib/components/badge/badge_spec.dart @@ -0,0 +1,23 @@ +import 'package:flutter/widgets.dart'; +import 'package:mix/mix.dart'; +import 'package:mix_annotations/mix_annotations.dart'; + +part 'badge_spec.g.dart'; + +@MixableSpec() +base class BadgeSpec extends Spec with _$BadgeSpec { + final BoxSpec container; + final TextSpec label; + + /// {@macro badge_spec_of} + static const of = _$BadgeSpec.of; + + static const from = _$BadgeSpec.from; + + const BadgeSpec({ + BoxSpec? container, + TextSpec? label, + super.animated, + }) : container = container ?? const BoxSpec(), + label = label ?? const TextSpec(); +} diff --git a/packages/remix/lib/components/badge/badge_spec.g.dart b/packages/remix/lib/components/badge/badge_spec.g.dart new file mode 100644 index 000000000..5d53385c9 --- /dev/null +++ b/packages/remix/lib/components/badge/badge_spec.g.dart @@ -0,0 +1,210 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'badge_spec.dart'; + +// ************************************************************************** +// MixableSpecGenerator +// ************************************************************************** + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$BadgeSpec on Spec { + static BadgeSpec from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? + const BadgeSpec(); + } + + /// {@template badge_spec_of} + /// Retrieves the [BadgeSpec] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [BadgeSpec] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [BadgeSpec]. + /// + /// Example: + /// + /// ```dart + /// final badgeSpec = BadgeSpec.of(context); + /// ``` + /// {@endtemplate} + static BadgeSpec of(BuildContext context) { + return _$BadgeSpec.from(Mix.of(context)); + } + + /// Creates a copy of this [BadgeSpec] but with the given fields + /// replaced with the new values. + @override + BadgeSpec copyWith({ + BoxSpec? container, + TextSpec? label, + AnimatedData? animated, + }) { + return BadgeSpec( + container: container ?? _$this.container, + label: label ?? _$this.label, + animated: animated ?? _$this.animated, + ); + } + + /// Linearly interpolates between this [BadgeSpec] and another [BadgeSpec] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [BadgeSpec] is returned. When [t] is 1.0, the [other] [BadgeSpec] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [BadgeSpec] is returned. + /// + /// If [other] is null, this method returns the current [BadgeSpec] instance. + /// + /// The interpolation is performed on each property of the [BadgeSpec] using the appropriate + /// interpolation method: + /// + /// - [BoxSpec.lerp] for [container]. + /// - [TextSpec.lerp] for [label]. + + /// For [animated], the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [BadgeSpec] is used. Otherwise, the value + /// from the [other] [BadgeSpec] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [BadgeSpec] configurations. + @override + BadgeSpec lerp(BadgeSpec? other, double t) { + if (other == null) return _$this; + + return BadgeSpec( + container: _$this.container.lerp(other.container, t), + label: _$this.label.lerp(other.label, t), + animated: t < 0.5 ? _$this.animated : other.animated, + ); + } + + /// The list of properties that constitute the state of this [BadgeSpec]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [BadgeSpec] instances for equality. + @override + List get props => [ + _$this.container, + _$this.label, + _$this.animated, + ]; + + BadgeSpec get _$this => this as BadgeSpec; +} + +/// Represents the attributes of a [BadgeSpec]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [BadgeSpec]. +/// +/// Use this class to configure the attributes of a [BadgeSpec] and pass it to +/// the [BadgeSpec] constructor. +final class BadgeSpecAttribute extends SpecAttribute { + final BoxSpecAttribute? container; + final TextSpecAttribute? label; + + const BadgeSpecAttribute({ + this.container, + this.label, + super.animated, + }); + + /// Resolves to [BadgeSpec] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final badgeSpec = BadgeSpecAttribute(...).resolve(mix); + /// ``` + @override + BadgeSpec resolve(MixData mix) { + return BadgeSpec( + container: container?.resolve(mix), + label: label?.resolve(mix), + animated: animated?.resolve(mix) ?? mix.animation, + ); + } + + /// Merges the properties of this [BadgeSpecAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [BadgeSpecAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + BadgeSpecAttribute merge(covariant BadgeSpecAttribute? other) { + if (other == null) return this; + + return BadgeSpecAttribute( + container: container?.merge(other.container) ?? other.container, + label: label?.merge(other.label) ?? other.label, + animated: animated?.merge(other.animated) ?? other.animated, + ); + } + + /// The list of properties that constitute the state of this [BadgeSpecAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [BadgeSpecAttribute] instances for equality. + @override + List get props => [ + container, + label, + animated, + ]; +} + +/// Utility class for configuring [BadgeSpecAttribute] properties. +/// +/// This class provides methods to set individual properties of a [BadgeSpecAttribute]. +/// Use the methods of this class to configure specific properties of a [BadgeSpecAttribute]. +base class BadgeSpecUtility + extends SpecUtility { + /// Utility for defining [BadgeSpecAttribute.container] + late final container = BoxSpecUtility((v) => only(container: v)); + + /// Utility for defining [BadgeSpecAttribute.label] + late final label = TextSpecUtility((v) => only(label: v)); + + /// Utility for defining [BadgeSpecAttribute.animated] + late final animated = AnimatedUtility((v) => only(animated: v)); + + BadgeSpecUtility(super.builder); + + static final self = BadgeSpecUtility((v) => v); + + /// Returns a new [BadgeSpecAttribute] with the specified properties. + @override + T only({ + BoxSpecAttribute? container, + TextSpecAttribute? label, + AnimatedDataDto? animated, + }) { + return builder(BadgeSpecAttribute( + container: container, + label: label, + animated: animated, + )); + } +} + +/// A tween that interpolates between two [BadgeSpec] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [BadgeSpec] specifications. +class BadgeSpecTween extends Tween { + BadgeSpecTween({ + super.begin, + super.end, + }); + + @override + BadgeSpec lerp(double t) { + if (begin == null && end == null) return const BadgeSpec(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} diff --git a/packages/remix/lib/components/badge/badge_style.dart b/packages/remix/lib/components/badge/badge_style.dart new file mode 100644 index 000000000..5bd0df0a1 --- /dev/null +++ b/packages/remix/lib/components/badge/badge_style.dart @@ -0,0 +1,73 @@ +// ignore_for_file: camel_case_types + +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/badge/badge_spec.dart'; +import 'package:remix/components/badge/badge_variants.dart'; +import 'package:remix/tokens/remix_tokens.dart'; + +final _badge = BadgeSpecUtility.self; +final _container = _badge.container; +final _label = _badge.label; + +Style get _baseStyle => Style( + _container.borderRadius(99), + _label.style.fontWeight(FontWeight.w500), + ); + +Style get _solidVariant => Style( + _container.color.ref($rx.color.accent()), + _label.style.color.ref($rx.color.neutral(1)), + ); + +Style get _softVariant => Style( + _container.color.ref($rx.color.accentAlpha(3)), + _label.style.color.ref($rx.color.accentAlpha(11)), + ); + +Style get _surfaceVariant => Style( + _container.color.ref($rx.color.accentAlpha(2)), + _label.style.color.ref($rx.color.accentAlpha(11)), + ); + +Style get _outlineVariant => Style( + _container.color(Colors.transparent), + _container.border.width(1), + _container.border.color.ref($rx.color.accentAlpha(8)), + _label.style.color.ref($rx.color.accentAlpha(11)), + ); + +final _smallVariant = Style( + _container.padding.vertical.ref($rx.space.space1), + _container.padding.horizontal.ref($rx.space.space2), + _label.style.as($rx.text.text1()), +); + +final _mediumVariant = Style( + _container.padding.vertical.ref($rx.space.space1), + _container.padding.horizontal.ref($rx.space.space3), + _label.style.as($rx.text.text2()), +); + +final _largeVariant = Style( + _container.padding.vertical.ref($rx.space.space2), + _container.padding.horizontal.ref($rx.space.space4), + _label.style.as($rx.text.text3()), +); + +Style badgeStyle(Style? style, List variants) { + return Style( + _baseStyle(), + + /// Size Variants + BadgeSize.small(_smallVariant()), + BadgeSize.medium(_mediumVariant()), + BadgeSize.large(_largeVariant()), + + // Type variants + BadgeVariant.solid(_solidVariant()), + BadgeVariant.soft(_softVariant()), + BadgeVariant.surface(_surfaceVariant()), + BadgeVariant.outline(_outlineVariant()), + ).merge(style).applyVariants(variants); +} diff --git a/packages/remix/lib/components/badge/badge_variants.dart b/packages/remix/lib/components/badge/badge_variants.dart new file mode 100644 index 000000000..becfaaecd --- /dev/null +++ b/packages/remix/lib/components/badge/badge_variants.dart @@ -0,0 +1,26 @@ +import 'package:remix/helpers/variant.dart'; + +abstract interface class IBadgeVariant extends RemixVariant { + const IBadgeVariant(String name) : super('badge.$name'); +} + +class BadgeVariant extends IBadgeVariant { + const BadgeVariant(String name) : super('variant.$name'); + + static const solid = BadgeVariant('solid'); + static const soft = BadgeVariant('soft'); + static const surface = BadgeVariant('surface'); + static const outline = BadgeVariant('outline'); + + static List get values => [solid, soft, surface, outline]; +} + +class BadgeSize extends IBadgeVariant { + const BadgeSize(String name) : super('size.$name'); + + static const small = BadgeSize('small'); + static const medium = BadgeSize('medium'); + static const large = BadgeSize('large'); + + static List get values => [small, medium, large]; +} diff --git a/packages/remix/lib/components/badge/badget_widget.dart b/packages/remix/lib/components/badge/badget_widget.dart new file mode 100644 index 000000000..feb09bfe1 --- /dev/null +++ b/packages/remix/lib/components/badge/badget_widget.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/badge/badge_spec.dart'; +import 'package:remix/components/badge/badge_style.dart'; +import 'package:remix/components/badge/badge_variants.dart'; + +class RxBadge extends StatelessWidget { + const RxBadge({ + super.key, + required this.label, + this.style, + this.size = BadgeSize.medium, + this.variant = BadgeVariant.soft, + }); + + final String label; + + /// Additional custom styling for the badge. + /// + /// This allows you to override or extend the default badge styling. + final Style? style; + + final BadgeSize size; + final BadgeVariant variant; + + @override + Widget build(BuildContext context) { + return SpecBuilder( + style: badgeStyle(style, [size, variant]), + builder: (context) { + final spec = BadgeSpec.of(context); + + return spec.container( + child: spec.label(label), + ); + }, + ); + } +} diff --git a/packages/remix/lib/components/button/button_spec.dart b/packages/remix/lib/components/button/button_spec.dart new file mode 100644 index 000000000..e3216dfe6 --- /dev/null +++ b/packages/remix/lib/components/button/button_spec.dart @@ -0,0 +1,35 @@ +import 'package:flutter/widgets.dart'; +import 'package:mix/mix.dart'; +import 'package:mix_annotations/mix_annotations.dart'; +import 'package:remix/components/spinner/spinner_spec.dart'; + +part 'button_spec.g.dart'; + +@MixableSpec() +base class ButtonSpec extends Spec with _$ButtonSpec { + final FlexSpec flex; + final BoxSpec container; + final IconSpec icon; + final TextSpec label; + + @MixableProperty(dto: MixableFieldDto(type: 'SpinnerSpecAttribute')) + final SpinnerSpec spinner; + + /// {@macro button_spec_of} + static const of = _$ButtonSpec.of; + + static const from = _$ButtonSpec.from; + + const ButtonSpec({ + BoxSpec? container, + FlexSpec? flex, + IconSpec? icon, + TextSpec? label, + SpinnerSpec? spinner, + super.animated, + }) : flex = flex ?? const FlexSpec(), + container = container ?? const BoxSpec(), + icon = icon ?? const IconSpec(), + label = label ?? const TextSpec(), + spinner = spinner ?? const SpinnerSpec(); +} diff --git a/packages/remix/lib/components/button/button_spec.g.dart b/packages/remix/lib/components/button/button_spec.g.dart new file mode 100644 index 000000000..f8ce7da0a --- /dev/null +++ b/packages/remix/lib/components/button/button_spec.g.dart @@ -0,0 +1,254 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'button_spec.dart'; + +// ************************************************************************** +// MixableSpecGenerator +// ************************************************************************** + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$ButtonSpec on Spec { + static ButtonSpec from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? + const ButtonSpec(); + } + + /// {@template button_spec_of} + /// Retrieves the [ButtonSpec] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [ButtonSpec] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [ButtonSpec]. + /// + /// Example: + /// + /// ```dart + /// final buttonSpec = ButtonSpec.of(context); + /// ``` + /// {@endtemplate} + static ButtonSpec of(BuildContext context) { + return _$ButtonSpec.from(Mix.of(context)); + } + + /// Creates a copy of this [ButtonSpec] but with the given fields + /// replaced with the new values. + @override + ButtonSpec copyWith({ + BoxSpec? container, + FlexSpec? flex, + IconSpec? icon, + TextSpec? label, + SpinnerSpec? spinner, + AnimatedData? animated, + }) { + return ButtonSpec( + container: container ?? _$this.container, + flex: flex ?? _$this.flex, + icon: icon ?? _$this.icon, + label: label ?? _$this.label, + spinner: spinner ?? _$this.spinner, + animated: animated ?? _$this.animated, + ); + } + + /// Linearly interpolates between this [ButtonSpec] and another [ButtonSpec] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [ButtonSpec] is returned. When [t] is 1.0, the [other] [ButtonSpec] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [ButtonSpec] is returned. + /// + /// If [other] is null, this method returns the current [ButtonSpec] instance. + /// + /// The interpolation is performed on each property of the [ButtonSpec] using the appropriate + /// interpolation method: + /// + /// - [BoxSpec.lerp] for [container]. + /// - [FlexSpec.lerp] for [flex]. + /// - [IconSpec.lerp] for [icon]. + /// - [TextSpec.lerp] for [label]. + + /// For [spinner] and [animated], the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [ButtonSpec] is used. Otherwise, the value + /// from the [other] [ButtonSpec] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [ButtonSpec] configurations. + @override + ButtonSpec lerp(ButtonSpec? other, double t) { + if (other == null) return _$this; + + return ButtonSpec( + container: _$this.container.lerp(other.container, t), + flex: _$this.flex.lerp(other.flex, t), + icon: _$this.icon.lerp(other.icon, t), + label: _$this.label.lerp(other.label, t), + spinner: t < 0.5 ? _$this.spinner : other.spinner, + animated: t < 0.5 ? _$this.animated : other.animated, + ); + } + + /// The list of properties that constitute the state of this [ButtonSpec]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [ButtonSpec] instances for equality. + @override + List get props => [ + _$this.container, + _$this.flex, + _$this.icon, + _$this.label, + _$this.spinner, + _$this.animated, + ]; + + ButtonSpec get _$this => this as ButtonSpec; +} + +/// Represents the attributes of a [ButtonSpec]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [ButtonSpec]. +/// +/// Use this class to configure the attributes of a [ButtonSpec] and pass it to +/// the [ButtonSpec] constructor. +final class ButtonSpecAttribute extends SpecAttribute { + final BoxSpecAttribute? container; + final FlexSpecAttribute? flex; + final IconSpecAttribute? icon; + final TextSpecAttribute? label; + final SpinnerSpecAttribute? spinner; + + const ButtonSpecAttribute({ + this.container, + this.flex, + this.icon, + this.label, + this.spinner, + super.animated, + }); + + /// Resolves to [ButtonSpec] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final buttonSpec = ButtonSpecAttribute(...).resolve(mix); + /// ``` + @override + ButtonSpec resolve(MixData mix) { + return ButtonSpec( + container: container?.resolve(mix), + flex: flex?.resolve(mix), + icon: icon?.resolve(mix), + label: label?.resolve(mix), + spinner: spinner?.resolve(mix), + animated: animated?.resolve(mix) ?? mix.animation, + ); + } + + /// Merges the properties of this [ButtonSpecAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [ButtonSpecAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + ButtonSpecAttribute merge(covariant ButtonSpecAttribute? other) { + if (other == null) return this; + + return ButtonSpecAttribute( + container: container?.merge(other.container) ?? other.container, + flex: flex?.merge(other.flex) ?? other.flex, + icon: icon?.merge(other.icon) ?? other.icon, + label: label?.merge(other.label) ?? other.label, + spinner: spinner?.merge(other.spinner) ?? other.spinner, + animated: animated?.merge(other.animated) ?? other.animated, + ); + } + + /// The list of properties that constitute the state of this [ButtonSpecAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [ButtonSpecAttribute] instances for equality. + @override + List get props => [ + container, + flex, + icon, + label, + spinner, + animated, + ]; +} + +/// Utility class for configuring [ButtonSpecAttribute] properties. +/// +/// This class provides methods to set individual properties of a [ButtonSpecAttribute]. +/// Use the methods of this class to configure specific properties of a [ButtonSpecAttribute]. +base class ButtonSpecUtility + extends SpecUtility { + /// Utility for defining [ButtonSpecAttribute.container] + late final container = BoxSpecUtility((v) => only(container: v)); + + /// Utility for defining [ButtonSpecAttribute.flex] + late final flex = FlexSpecUtility((v) => only(flex: v)); + + /// Utility for defining [ButtonSpecAttribute.icon] + late final icon = IconSpecUtility((v) => only(icon: v)); + + /// Utility for defining [ButtonSpecAttribute.label] + late final label = TextSpecUtility((v) => only(label: v)); + + /// Utility for defining [ButtonSpecAttribute.spinner] + late final spinner = SpinnerSpecUtility((v) => only(spinner: v)); + + /// Utility for defining [ButtonSpecAttribute.animated] + late final animated = AnimatedUtility((v) => only(animated: v)); + + ButtonSpecUtility(super.builder); + + static final self = ButtonSpecUtility((v) => v); + + /// Returns a new [ButtonSpecAttribute] with the specified properties. + @override + T only({ + BoxSpecAttribute? container, + FlexSpecAttribute? flex, + IconSpecAttribute? icon, + TextSpecAttribute? label, + SpinnerSpecAttribute? spinner, + AnimatedDataDto? animated, + }) { + return builder(ButtonSpecAttribute( + container: container, + flex: flex, + icon: icon, + label: label, + spinner: spinner, + animated: animated, + )); + } +} + +/// A tween that interpolates between two [ButtonSpec] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [ButtonSpec] specifications. +class ButtonSpecTween extends Tween { + ButtonSpecTween({ + super.begin, + super.end, + }); + + @override + ButtonSpec lerp(double t) { + if (begin == null && end == null) return const ButtonSpec(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} diff --git a/packages/remix/lib/components/button/button_style.dart b/packages/remix/lib/components/button/button_style.dart new file mode 100644 index 000000000..9a07a3a30 --- /dev/null +++ b/packages/remix/lib/components/button/button_style.dart @@ -0,0 +1,168 @@ +// ignore_for_file: camel_case_types + +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/button/button_spec.dart'; +import 'package:remix/components/button/button_variants.dart'; +import 'package:remix/tokens/remix_tokens.dart'; + +final _util = ButtonSpecUtility.self; +final _label = _util.label; +final _spinner = _util.spinner; +final _container = _util.container; +final _flex = _util.flex; + +/// This applies to the icon, label, and spinner +final _items = _util.items; + +Style get _baseStyle => Style( + _flex.gap(0), + _flex.mainAxisAlignment.center(), + _flex.crossAxisAlignment.center(), + _flex.mainAxisSize.min(), + _container.borderRadius(6), + _spinner.strokeWidth(1), + _label.style.fontWeight(FontWeight.w500), + _label.textHeightBehavior( + const TextHeightBehavior( + applyHeightToFirstAscent: false, + applyHeightToLastDescent: true, + ), + ), + ); + +Style get _onDisabledForeground => Style( + $on.disabled( + _items.color.ref($rx.color.neutralAlpha(7)), + ), + ); + +Style get _solidVariant => Style( + _container.color.ref($rx.color.accent()), + _items.color.ref($rx.color.white()), + $on.hover( + _container.color.ref($rx.color.accent(10)), + ), + $on.disabled( + _container.color.ref($rx.color.neutralAlpha(3)), + ), + ); + +Style get _softVariant => Style( + _container.color.ref($rx.color.accentAlpha(3)), + _items.color.ref($rx.color.accentAlpha(11)), + $on.hover( + _container.color.ref($rx.color.accentAlpha(4)), + ), + $on.disabled( + _container.color.ref($rx.color.neutralAlpha(3)), + ), + ); + +Style get _outlineVariant => Style( + _container.color(Colors.transparent), + _container.border.width(1.5), + _container.border.strokeAlign(0), + _container.border.color.ref($rx.color.accentAlpha(8)), + _items.color.ref($rx.color.accentAlpha(11)), + $on.hover( + _container.color.ref($rx.color.accentAlpha(2)), + ), + $on.disabled( + _container.border.color.ref($rx.color.neutralAlpha(8)), + _container.color.transparent(), + ), + ); +Style get _surfaceVariant => Style( + _outlineVariant(), + _container.color.ref($rx.color.accentAlpha(3)), + $on.hover( + _container.color.ref($rx.color.accentAlpha(4)), + _container.border.color.ref($rx.color.accentAlpha(8)), + ), + $on.disabled( + _container.color.ref($rx.color.neutralAlpha(2)), + ), + ); + +Style get _ghostVariant => Style( + _container.border.style.none(), + _container.color(Colors.transparent), + _items.color.ref($rx.color.accentAlpha(11)), + $on.hover( + _container.color.ref($rx.color.accentAlpha(3)), + ), + ); + +Style get _smallVariant => Style( + _label.style.ref($rx.text.text1), + _container.padding.vertical.ref($rx.space(1)), + _container.padding.horizontal.ref($rx.space(2)), + _flex.gap.ref($rx.space(1)), + _items.size(12), + ); + +Style get _mediumVariant => Style( + _container.padding.vertical.ref($rx.space(2)), + _container.padding.horizontal.ref($rx.space(3)), + _flex.gap.ref($rx.space(2)), + _label.style.ref($rx.text.text2), + _items.size(14), + ); + +Style get _largeVariant => Style( + _container.padding.vertical.ref($rx.space(2)), + _container.padding.horizontal.ref($rx.space(4)), + _flex.gap.ref($rx.space(3)), + _label.style.ref($rx.text.text3), + _items.size(16), + ); + +Style get _xLargeVariant => Style( + _container.padding.vertical.ref($rx.space(3)), + _container.padding.horizontal.ref($rx.space(5)), + _flex.gap.ref($rx.space(3)), + _label.style.ref($rx.text.text4), + _items.size(18), + ); + +Style buildDefaultButtonStyle() { + return Style( + _baseStyle(), + + /// Size Variants + ButtonSize.small(_smallVariant()), + ButtonSize.medium(_mediumVariant()), + ButtonSize.large(_largeVariant()), + ButtonSize.xlarge(_xLargeVariant()), + + _onDisabledForeground(), + + // Type variants + ButtonVariant.solid(_solidVariant()), + ButtonVariant.surface(_surfaceVariant()), + ButtonVariant.soft(_softVariant()), + ButtonVariant.outline(_outlineVariant()), + ButtonVariant.ghost(_ghostVariant()), + ); +} + +extension ButtonSpecUtilityX on ButtonSpecUtility { + ForegroundUtility get items => ForegroundUtility((v) { + return only().merge(label.style + .only(color: v.color) + .merge(icon.only(color: v.color, size: v.size)) + .merge(spinner.only(color: v.color, size: v.size))) as T; + }); +} + +class ForegroundUtility + extends MixUtility { + ForegroundUtility(super.builder); + late final color = ColorUtility((v) => only(color: v)); + + late final size = FontSizeUtility((v) => only(size: v)); + T only({ColorDto? color, double? size}) { + return builder((color: color, size: size)); + } +} diff --git a/packages/remix/lib/components/button/button_variants.dart b/packages/remix/lib/components/button/button_variants.dart new file mode 100644 index 000000000..2047c2739 --- /dev/null +++ b/packages/remix/lib/components/button/button_variants.dart @@ -0,0 +1,34 @@ +import 'package:remix/helpers/variant.dart'; + +interface class IButtonVariant extends RemixVariant { + const IButtonVariant(String name) : super('button.$name'); +} + +class ButtonSize extends IButtonVariant { + const ButtonSize(String name) : super('size.$name'); + + static const small = ButtonSize('small'); + static const medium = ButtonSize('medium'); + static const large = ButtonSize('large'); + static const xlarge = ButtonSize('xlarge'); + + static List get values => [small, medium, large, xlarge]; +} + +class ButtonVariant extends IButtonVariant { + const ButtonVariant(String name) : super('variant.$name'); + + static const solid = ButtonVariant('solid'); + static const soft = ButtonVariant('soft'); + static const surface = ButtonVariant('surface'); + static const outline = ButtonVariant('outline'); + static const ghost = ButtonVariant('ghost'); + + static List get values => [ + solid, + soft, + surface, + outline, + ghost, + ]; +} diff --git a/packages/remix/lib/components/button/button_widget.dart b/packages/remix/lib/components/button/button_widget.dart new file mode 100644 index 000000000..df7672aa5 --- /dev/null +++ b/packages/remix/lib/components/button/button_widget.dart @@ -0,0 +1,122 @@ +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/button/button_spec.dart'; +import 'package:remix/components/button/button_style.dart'; +import 'package:remix/components/button/button_variants.dart'; + +/// A customizable button component with various styling options. +/// +/// The [RxButton] allows you to create buttons with different variants, sizes, +/// and icons. You can also disable the button or show a loading state. +/// +/// Example usage: +/// +/// ```dart +/// RxButton( +/// label: 'Click me', +/// onPressed: () {}, +/// iconLeft: Icons.add, +/// ) +/// ``` +class RxButton extends StatelessWidget { + const RxButton({ + super.key, + required this.label, + this.disabled = false, + this.loading = false, + this.iconLeft, + this.iconRight, + this.type = ButtonVariant.solid, + this.size = ButtonSize.medium, + required this.onPressed, + this.style, + }); + + /// The text label displayed on the button. + final String label; + + /// Whether the button is disabled. + /// + /// When disabled, the button will not respond to user interactions. + final bool disabled; + + /// Whether the button is in a loading state. + /// + /// When loading, the button will display a loading indicator and + /// will not respond to user interactions. + final bool loading; + + /// An optional icon to display on the left side of the label. + final IconData? iconLeft; + + /// An optional icon to display on the right side of the label. + final IconData? iconRight; + + /// The button variant. + final ButtonVariant type; + + /// The button size. + final ButtonSize size; + + /// The callback function called when the button is pressed. + /// + /// This callback will not be called if the button is disabled or in a loading state. + final VoidCallback? onPressed; + + /// Additional custom styling for the button. + /// + /// This allows you to override or extend the default button styling. + final Style? style; + + bool get _hasIcon => iconLeft != null || iconRight != null; + + Style _buildStyle() { + return buildDefaultButtonStyle() + .merge(style) + .applyVariants([size, type]).animate(); + } + + Widget _buildLoadingOverlay(ButtonSpec spec, Widget child) { + return loading + ? Stack( + alignment: Alignment.center, + children: [ + spec.spinner(), + Opacity(opacity: 0.0, child: child), + ], + ) + : child; + } + + Widget _buildChildren(ButtonSpec spec) { + final flexWidget = spec.flex( + direction: Axis.horizontal, + children: [ + if (iconLeft != null) spec.icon(iconLeft), + // If there is no icon always render the label + if (label.isNotEmpty || !_hasIcon) spec.label(label), + if (iconRight != null) spec.icon(iconRight), + ], + ); + + return loading ? _buildLoadingOverlay(spec, flexWidget) : flexWidget; + } + + @override + Widget build(BuildContext context) { + final isDisabled = disabled || loading; + return Pressable( + onPress: disabled || loading ? null : onPressed, + enabled: !isDisabled, + child: SpecBuilder( + style: _buildStyle(), + builder: (context) { + final spec = ButtonSpec.of(context); + + return spec.container( + child: _buildChildren(spec), + ); + }), + ); + } +} diff --git a/packages/remix/lib/components/callout/callout_spec.dart b/packages/remix/lib/components/callout/callout_spec.dart new file mode 100644 index 000000000..7625053c0 --- /dev/null +++ b/packages/remix/lib/components/callout/callout_spec.dart @@ -0,0 +1,29 @@ +import 'package:flutter/widgets.dart'; +import 'package:mix/mix.dart'; +import 'package:mix_annotations/mix_annotations.dart'; + +part 'callout_spec.g.dart'; + +@MixableSpec() +base class CalloutSpec extends Spec with _$CalloutSpec { + final BoxSpec container; + final FlexSpec flex; + final IconSpec icon; + final TextSpec text; + + /// {@macro callout_spec_of} + static const of = _$CalloutSpec.of; + + static const from = _$CalloutSpec.from; + + const CalloutSpec({ + BoxSpec? container, + FlexSpec? flex, + IconSpec? icon, + TextSpec? text, + super.animated, + }) : container = container ?? const BoxSpec(), + flex = flex ?? const FlexSpec(), + icon = icon ?? const IconSpec(), + text = text ?? const TextSpec(); +} diff --git a/packages/remix/lib/components/callout/callout_spec.g.dart b/packages/remix/lib/components/callout/callout_spec.g.dart new file mode 100644 index 000000000..22c716db1 --- /dev/null +++ b/packages/remix/lib/components/callout/callout_spec.g.dart @@ -0,0 +1,240 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'callout_spec.dart'; + +// ************************************************************************** +// MixableSpecGenerator +// ************************************************************************** + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$CalloutSpec on Spec { + static CalloutSpec from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? + const CalloutSpec(); + } + + /// {@template callout_spec_of} + /// Retrieves the [CalloutSpec] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [CalloutSpec] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [CalloutSpec]. + /// + /// Example: + /// + /// ```dart + /// final calloutSpec = CalloutSpec.of(context); + /// ``` + /// {@endtemplate} + static CalloutSpec of(BuildContext context) { + return _$CalloutSpec.from(Mix.of(context)); + } + + /// Creates a copy of this [CalloutSpec] but with the given fields + /// replaced with the new values. + @override + CalloutSpec copyWith({ + BoxSpec? container, + FlexSpec? flex, + IconSpec? icon, + TextSpec? text, + AnimatedData? animated, + }) { + return CalloutSpec( + container: container ?? _$this.container, + flex: flex ?? _$this.flex, + icon: icon ?? _$this.icon, + text: text ?? _$this.text, + animated: animated ?? _$this.animated, + ); + } + + /// Linearly interpolates between this [CalloutSpec] and another [CalloutSpec] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [CalloutSpec] is returned. When [t] is 1.0, the [other] [CalloutSpec] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [CalloutSpec] is returned. + /// + /// If [other] is null, this method returns the current [CalloutSpec] instance. + /// + /// The interpolation is performed on each property of the [CalloutSpec] using the appropriate + /// interpolation method: + /// + /// - [BoxSpec.lerp] for [container]. + /// - [FlexSpec.lerp] for [flex]. + /// - [IconSpec.lerp] for [icon]. + /// - [TextSpec.lerp] for [text]. + + /// For [animated], the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [CalloutSpec] is used. Otherwise, the value + /// from the [other] [CalloutSpec] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [CalloutSpec] configurations. + @override + CalloutSpec lerp(CalloutSpec? other, double t) { + if (other == null) return _$this; + + return CalloutSpec( + container: _$this.container.lerp(other.container, t), + flex: _$this.flex.lerp(other.flex, t), + icon: _$this.icon.lerp(other.icon, t), + text: _$this.text.lerp(other.text, t), + animated: t < 0.5 ? _$this.animated : other.animated, + ); + } + + /// The list of properties that constitute the state of this [CalloutSpec]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [CalloutSpec] instances for equality. + @override + List get props => [ + _$this.container, + _$this.flex, + _$this.icon, + _$this.text, + _$this.animated, + ]; + + CalloutSpec get _$this => this as CalloutSpec; +} + +/// Represents the attributes of a [CalloutSpec]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [CalloutSpec]. +/// +/// Use this class to configure the attributes of a [CalloutSpec] and pass it to +/// the [CalloutSpec] constructor. +final class CalloutSpecAttribute extends SpecAttribute { + final BoxSpecAttribute? container; + final FlexSpecAttribute? flex; + final IconSpecAttribute? icon; + final TextSpecAttribute? text; + + const CalloutSpecAttribute({ + this.container, + this.flex, + this.icon, + this.text, + super.animated, + }); + + /// Resolves to [CalloutSpec] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final calloutSpec = CalloutSpecAttribute(...).resolve(mix); + /// ``` + @override + CalloutSpec resolve(MixData mix) { + return CalloutSpec( + container: container?.resolve(mix), + flex: flex?.resolve(mix), + icon: icon?.resolve(mix), + text: text?.resolve(mix), + animated: animated?.resolve(mix) ?? mix.animation, + ); + } + + /// Merges the properties of this [CalloutSpecAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [CalloutSpecAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + CalloutSpecAttribute merge(covariant CalloutSpecAttribute? other) { + if (other == null) return this; + + return CalloutSpecAttribute( + container: container?.merge(other.container) ?? other.container, + flex: flex?.merge(other.flex) ?? other.flex, + icon: icon?.merge(other.icon) ?? other.icon, + text: text?.merge(other.text) ?? other.text, + animated: animated?.merge(other.animated) ?? other.animated, + ); + } + + /// The list of properties that constitute the state of this [CalloutSpecAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [CalloutSpecAttribute] instances for equality. + @override + List get props => [ + container, + flex, + icon, + text, + animated, + ]; +} + +/// Utility class for configuring [CalloutSpecAttribute] properties. +/// +/// This class provides methods to set individual properties of a [CalloutSpecAttribute]. +/// Use the methods of this class to configure specific properties of a [CalloutSpecAttribute]. +base class CalloutSpecUtility + extends SpecUtility { + /// Utility for defining [CalloutSpecAttribute.container] + late final container = BoxSpecUtility((v) => only(container: v)); + + /// Utility for defining [CalloutSpecAttribute.flex] + late final flex = FlexSpecUtility((v) => only(flex: v)); + + /// Utility for defining [CalloutSpecAttribute.icon] + late final icon = IconSpecUtility((v) => only(icon: v)); + + /// Utility for defining [CalloutSpecAttribute.text] + late final text = TextSpecUtility((v) => only(text: v)); + + /// Utility for defining [CalloutSpecAttribute.animated] + late final animated = AnimatedUtility((v) => only(animated: v)); + + CalloutSpecUtility(super.builder); + + static final self = CalloutSpecUtility((v) => v); + + /// Returns a new [CalloutSpecAttribute] with the specified properties. + @override + T only({ + BoxSpecAttribute? container, + FlexSpecAttribute? flex, + IconSpecAttribute? icon, + TextSpecAttribute? text, + AnimatedDataDto? animated, + }) { + return builder(CalloutSpecAttribute( + container: container, + flex: flex, + icon: icon, + text: text, + animated: animated, + )); + } +} + +/// A tween that interpolates between two [CalloutSpec] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [CalloutSpec] specifications. +class CalloutSpecTween extends Tween { + CalloutSpecTween({ + super.begin, + super.end, + }); + + @override + CalloutSpec lerp(double t) { + if (begin == null && end == null) return const CalloutSpec(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} diff --git a/packages/remix/lib/components/callout/callout_style.dart b/packages/remix/lib/components/callout/callout_style.dart new file mode 100644 index 000000000..c9ae9ae44 --- /dev/null +++ b/packages/remix/lib/components/callout/callout_style.dart @@ -0,0 +1,50 @@ +// ignore_for_file: camel_case_types + +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/callout/callout_spec.dart'; +import 'package:remix/components/callout/callout_variants.dart'; +import 'package:remix/tokens/remix_tokens.dart'; + +final _callout = CalloutSpecUtility.self; +final _container = _callout.container; +final _flex = _callout.flex; +final _icon = _callout.icon; +final _text = _callout.text; + +Style get _baseStyle => Style( + _container.borderRadius(8), + _container.padding(16), + _flex.gap(16), + _icon.size(24), + _icon.color.ref($rx.color.accentAlpha(11)), + _text.style.color.ref($rx.color.accentAlpha(11)), + _icon.size(20), + ); + +Style get _softVariant => Style( + _container.color.ref($rx.color.accentAlpha(3)), + ); + +Style get _surfaceVariant => Style( + _container.color.ref($rx.color.accentAlpha(2)), + _container.border.width(1), + _container.border.color.ref($rx.color.accentAlpha(5)), + ); + +Style get _outlineVariant => Style( + _container.color(Colors.transparent), + _container.border.width(1), + _container.border.color.ref($rx.color.accentAlpha(8)), + ); + +Style calloutStyle(Style? style, List variants) { + return Style( + _baseStyle(), + + // variants + CalloutVariant.soft(_softVariant()), + CalloutVariant.surface(_surfaceVariant()), + CalloutVariant.outline(_outlineVariant()), + ).merge(style).applyVariants(variants); +} diff --git a/packages/remix/lib/components/callout/callout_variants.dart b/packages/remix/lib/components/callout/callout_variants.dart new file mode 100644 index 000000000..4d906425f --- /dev/null +++ b/packages/remix/lib/components/callout/callout_variants.dart @@ -0,0 +1,15 @@ +import 'package:remix/helpers/variant.dart'; + +abstract interface class ICalloutVariant extends RemixVariant { + const ICalloutVariant(String name) : super('callout.$name'); +} + +class CalloutVariant extends ICalloutVariant { + const CalloutVariant(String name) : super('variant.$name'); + + static const soft = CalloutVariant('soft'); + static const surface = CalloutVariant('surface'); + static const outline = CalloutVariant('outline'); + + static List get values => [soft, surface, outline]; +} diff --git a/packages/remix/lib/components/callout/callout_widget.dart b/packages/remix/lib/components/callout/callout_widget.dart new file mode 100644 index 000000000..3d1015375 --- /dev/null +++ b/packages/remix/lib/components/callout/callout_widget.dart @@ -0,0 +1,45 @@ +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/callout/callout_spec.dart'; +import 'package:remix/components/callout/callout_style.dart'; +import 'package:remix/components/callout/callout_variants.dart'; + +class RxCallout extends StatelessWidget { + const RxCallout({ + super.key, + required this.text, + this.icon, + this.style, + this.variant = CalloutVariant.soft, + }); + + final String text; + final IconData? icon; + + /// Additional custom styling for the callout. + /// + /// This allows you to override or extend the default callout styling. + final Style? style; + + final CalloutVariant variant; + + @override + Widget build(BuildContext context) { + return SpecBuilder( + style: calloutStyle(style, [variant]), + builder: (context) { + final spec = CalloutSpec.of(context); + + return spec.container( + child: spec.flex( + direction: Axis.horizontal, + children: [ + if (icon != null) spec.icon(icon!), + spec.text(text), + ], + ), + ); + }, + ); + } +} diff --git a/packages/remix/lib/components/card/card_spec.dart b/packages/remix/lib/components/card/card_spec.dart new file mode 100644 index 000000000..f7d7f4889 --- /dev/null +++ b/packages/remix/lib/components/card/card_spec.dart @@ -0,0 +1,24 @@ +import 'package:flutter/widgets.dart'; +import 'package:mix/mix.dart'; +import 'package:mix_annotations/mix_annotations.dart'; + +part 'card_spec.g.dart'; + +@MixableSpec() +base class CardSpec extends Spec with _$CardSpec { + final BoxSpec container; + + final FlexSpec flex; + + /// {@macro card_spec_of} + static const of = _$CardSpec.of; + + static const from = _$CardSpec.from; + + const CardSpec({ + BoxSpec? container, + FlexSpec? flex, + super.animated, + }) : container = container ?? const BoxSpec(), + flex = flex ?? const FlexSpec(); +} diff --git a/packages/remix/lib/components/card/card_spec.g.dart b/packages/remix/lib/components/card/card_spec.g.dart new file mode 100644 index 000000000..d85e89a76 --- /dev/null +++ b/packages/remix/lib/components/card/card_spec.g.dart @@ -0,0 +1,210 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'card_spec.dart'; + +// ************************************************************************** +// MixableSpecGenerator +// ************************************************************************** + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$CardSpec on Spec { + static CardSpec from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? + const CardSpec(); + } + + /// {@template card_spec_of} + /// Retrieves the [CardSpec] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [CardSpec] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [CardSpec]. + /// + /// Example: + /// + /// ```dart + /// final cardSpec = CardSpec.of(context); + /// ``` + /// {@endtemplate} + static CardSpec of(BuildContext context) { + return _$CardSpec.from(Mix.of(context)); + } + + /// Creates a copy of this [CardSpec] but with the given fields + /// replaced with the new values. + @override + CardSpec copyWith({ + BoxSpec? container, + FlexSpec? flex, + AnimatedData? animated, + }) { + return CardSpec( + container: container ?? _$this.container, + flex: flex ?? _$this.flex, + animated: animated ?? _$this.animated, + ); + } + + /// Linearly interpolates between this [CardSpec] and another [CardSpec] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [CardSpec] is returned. When [t] is 1.0, the [other] [CardSpec] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [CardSpec] is returned. + /// + /// If [other] is null, this method returns the current [CardSpec] instance. + /// + /// The interpolation is performed on each property of the [CardSpec] using the appropriate + /// interpolation method: + /// + /// - [BoxSpec.lerp] for [container]. + /// - [FlexSpec.lerp] for [flex]. + + /// For [animated], the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [CardSpec] is used. Otherwise, the value + /// from the [other] [CardSpec] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [CardSpec] configurations. + @override + CardSpec lerp(CardSpec? other, double t) { + if (other == null) return _$this; + + return CardSpec( + container: _$this.container.lerp(other.container, t), + flex: _$this.flex.lerp(other.flex, t), + animated: t < 0.5 ? _$this.animated : other.animated, + ); + } + + /// The list of properties that constitute the state of this [CardSpec]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [CardSpec] instances for equality. + @override + List get props => [ + _$this.container, + _$this.flex, + _$this.animated, + ]; + + CardSpec get _$this => this as CardSpec; +} + +/// Represents the attributes of a [CardSpec]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [CardSpec]. +/// +/// Use this class to configure the attributes of a [CardSpec] and pass it to +/// the [CardSpec] constructor. +final class CardSpecAttribute extends SpecAttribute { + final BoxSpecAttribute? container; + final FlexSpecAttribute? flex; + + const CardSpecAttribute({ + this.container, + this.flex, + super.animated, + }); + + /// Resolves to [CardSpec] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final cardSpec = CardSpecAttribute(...).resolve(mix); + /// ``` + @override + CardSpec resolve(MixData mix) { + return CardSpec( + container: container?.resolve(mix), + flex: flex?.resolve(mix), + animated: animated?.resolve(mix) ?? mix.animation, + ); + } + + /// Merges the properties of this [CardSpecAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [CardSpecAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + CardSpecAttribute merge(covariant CardSpecAttribute? other) { + if (other == null) return this; + + return CardSpecAttribute( + container: container?.merge(other.container) ?? other.container, + flex: flex?.merge(other.flex) ?? other.flex, + animated: animated?.merge(other.animated) ?? other.animated, + ); + } + + /// The list of properties that constitute the state of this [CardSpecAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [CardSpecAttribute] instances for equality. + @override + List get props => [ + container, + flex, + animated, + ]; +} + +/// Utility class for configuring [CardSpecAttribute] properties. +/// +/// This class provides methods to set individual properties of a [CardSpecAttribute]. +/// Use the methods of this class to configure specific properties of a [CardSpecAttribute]. +base class CardSpecUtility + extends SpecUtility { + /// Utility for defining [CardSpecAttribute.container] + late final container = BoxSpecUtility((v) => only(container: v)); + + /// Utility for defining [CardSpecAttribute.flex] + late final flex = FlexSpecUtility((v) => only(flex: v)); + + /// Utility for defining [CardSpecAttribute.animated] + late final animated = AnimatedUtility((v) => only(animated: v)); + + CardSpecUtility(super.builder); + + static final self = CardSpecUtility((v) => v); + + /// Returns a new [CardSpecAttribute] with the specified properties. + @override + T only({ + BoxSpecAttribute? container, + FlexSpecAttribute? flex, + AnimatedDataDto? animated, + }) { + return builder(CardSpecAttribute( + container: container, + flex: flex, + animated: animated, + )); + } +} + +/// A tween that interpolates between two [CardSpec] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [CardSpec] specifications. +class CardSpecTween extends Tween { + CardSpecTween({ + super.begin, + super.end, + }); + + @override + CardSpec lerp(double t) { + if (begin == null && end == null) return const CardSpec(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} diff --git a/packages/remix/lib/components/card/card_style.dart b/packages/remix/lib/components/card/card_style.dart new file mode 100644 index 000000000..472eb2f71 --- /dev/null +++ b/packages/remix/lib/components/card/card_style.dart @@ -0,0 +1,39 @@ +import 'package:mix/mix.dart'; +import 'package:remix/components/card/card_spec.dart'; +import 'package:remix/components/card/card_variants.dart'; +import 'package:remix/tokens/remix_tokens.dart'; + +final _util = CardSpecUtility.self; +final _container = _util.container; +final _flex = _util.flex; +Style get _baseStyle => Style( + _container.padding(16), + _flex.column(), + _flex.gap(24), + _container.borderRadius(8), + ); + +Style get _solidVariant => Style( + _container.border.color.ref($rx.color.neutral(1)), + ); + +Style get _softVariant => Style( + _container.color.ref($rx.color.neutralAlpha(3)), + ); + +Style get _surfaceVariant => Style( + _container.color.ref($rx.color.neutralAlpha(3)), + _container.border.color.ref($rx.color.neutralAlpha(7)), + _container.border.strokeAlign(1), + ); + +Style get _ghostVariant => Style(); +Style buildCardstyle(Style? style) { + return Style( + _baseStyle(), + CardVariant.solid(_solidVariant()), + CardVariant.soft(_softVariant()), + CardVariant.ghost(_ghostVariant()), + CardVariant.surface(_surfaceVariant()), + ).merge(style); +} diff --git a/packages/remix/lib/components/card/card_variants.dart b/packages/remix/lib/components/card/card_variants.dart new file mode 100644 index 000000000..ddb325d8a --- /dev/null +++ b/packages/remix/lib/components/card/card_variants.dart @@ -0,0 +1,21 @@ +import 'package:remix/helpers/variant.dart'; + +interface class ICardVariant extends RemixVariant { + const ICardVariant(String name) : super('card.$name'); +} + +class CardVariant extends ICardVariant { + const CardVariant(String name) : super('variant.$name'); + + static const solid = CardVariant('solid'); + static const soft = CardVariant('soft'); + static const surface = CardVariant('surface'); + static const ghost = CardVariant('ghost'); + + static List get values => [ + solid, + soft, + surface, + ghost, + ]; +} diff --git a/packages/remix/lib/components/card/card_widget.dart b/packages/remix/lib/components/card/card_widget.dart new file mode 100644 index 000000000..9c0b3108a --- /dev/null +++ b/packages/remix/lib/components/card/card_widget.dart @@ -0,0 +1,45 @@ +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/card/card_spec.dart'; +import 'package:remix/components/card/card_style.dart'; +import 'package:remix/components/card/card_variants.dart'; + +class RxCard extends StatelessWidget { + const RxCard({ + super.key, + required this.children, + this.variant = CardVariant.solid, + this.style, + }); + + /// The list of child widgets to be displayed inside the card. + final List children; + + final CardVariant variant; + + /// Additional custom styling for the card. + /// + /// This allows you to override or extend the default card styling. + final Style? style; + + Style _buildStyle() { + return buildCardstyle(style).applyVariant(variant).animate(); + } + + @override + Widget build(BuildContext context) { + return SpecBuilder( + style: _buildStyle(), + builder: (context) { + final spec = CardSpec.of(context); + + return spec.container( + child: spec.flex( + direction: Axis.vertical, + children: children, + ), + ); + }, + ); + } +} diff --git a/packages/remix/lib/components/checkbox/checkbox_spec.dart b/packages/remix/lib/components/checkbox/checkbox_spec.dart new file mode 100644 index 000000000..99fe7be47 --- /dev/null +++ b/packages/remix/lib/components/checkbox/checkbox_spec.dart @@ -0,0 +1,23 @@ +import 'package:flutter/widgets.dart'; +import 'package:mix/mix.dart'; +import 'package:mix_annotations/mix_annotations.dart'; + +part 'checkbox_spec.g.dart'; + +@MixableSpec() +base class CheckboxSpec extends Spec with _$CheckboxSpec { + final BoxSpec container; + final IconSpec indicator; + + /// {@macro button_spec_of} + static const of = _$CheckboxSpec.of; + + static const from = _$CheckboxSpec.from; + + const CheckboxSpec({ + BoxSpec? container, + IconSpec? indicator, + super.animated, + }) : container = container ?? const BoxSpec(), + indicator = indicator ?? const IconSpec(); +} diff --git a/packages/remix/lib/components/checkbox/checkbox_spec.g.dart b/packages/remix/lib/components/checkbox/checkbox_spec.g.dart new file mode 100644 index 000000000..596dcdac7 --- /dev/null +++ b/packages/remix/lib/components/checkbox/checkbox_spec.g.dart @@ -0,0 +1,210 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'checkbox_spec.dart'; + +// ************************************************************************** +// MixableSpecGenerator +// ************************************************************************** + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$CheckboxSpec on Spec { + static CheckboxSpec from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? + const CheckboxSpec(); + } + + /// {@template checkbox_spec_of} + /// Retrieves the [CheckboxSpec] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [CheckboxSpec] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [CheckboxSpec]. + /// + /// Example: + /// + /// ```dart + /// final checkboxSpec = CheckboxSpec.of(context); + /// ``` + /// {@endtemplate} + static CheckboxSpec of(BuildContext context) { + return _$CheckboxSpec.from(Mix.of(context)); + } + + /// Creates a copy of this [CheckboxSpec] but with the given fields + /// replaced with the new values. + @override + CheckboxSpec copyWith({ + BoxSpec? container, + IconSpec? indicator, + AnimatedData? animated, + }) { + return CheckboxSpec( + container: container ?? _$this.container, + indicator: indicator ?? _$this.indicator, + animated: animated ?? _$this.animated, + ); + } + + /// Linearly interpolates between this [CheckboxSpec] and another [CheckboxSpec] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [CheckboxSpec] is returned. When [t] is 1.0, the [other] [CheckboxSpec] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [CheckboxSpec] is returned. + /// + /// If [other] is null, this method returns the current [CheckboxSpec] instance. + /// + /// The interpolation is performed on each property of the [CheckboxSpec] using the appropriate + /// interpolation method: + /// + /// - [BoxSpec.lerp] for [container]. + /// - [IconSpec.lerp] for [indicator]. + + /// For [animated], the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [CheckboxSpec] is used. Otherwise, the value + /// from the [other] [CheckboxSpec] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [CheckboxSpec] configurations. + @override + CheckboxSpec lerp(CheckboxSpec? other, double t) { + if (other == null) return _$this; + + return CheckboxSpec( + container: _$this.container.lerp(other.container, t), + indicator: _$this.indicator.lerp(other.indicator, t), + animated: t < 0.5 ? _$this.animated : other.animated, + ); + } + + /// The list of properties that constitute the state of this [CheckboxSpec]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [CheckboxSpec] instances for equality. + @override + List get props => [ + _$this.container, + _$this.indicator, + _$this.animated, + ]; + + CheckboxSpec get _$this => this as CheckboxSpec; +} + +/// Represents the attributes of a [CheckboxSpec]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [CheckboxSpec]. +/// +/// Use this class to configure the attributes of a [CheckboxSpec] and pass it to +/// the [CheckboxSpec] constructor. +final class CheckboxSpecAttribute extends SpecAttribute { + final BoxSpecAttribute? container; + final IconSpecAttribute? indicator; + + const CheckboxSpecAttribute({ + this.container, + this.indicator, + super.animated, + }); + + /// Resolves to [CheckboxSpec] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final checkboxSpec = CheckboxSpecAttribute(...).resolve(mix); + /// ``` + @override + CheckboxSpec resolve(MixData mix) { + return CheckboxSpec( + container: container?.resolve(mix), + indicator: indicator?.resolve(mix), + animated: animated?.resolve(mix) ?? mix.animation, + ); + } + + /// Merges the properties of this [CheckboxSpecAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [CheckboxSpecAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + CheckboxSpecAttribute merge(covariant CheckboxSpecAttribute? other) { + if (other == null) return this; + + return CheckboxSpecAttribute( + container: container?.merge(other.container) ?? other.container, + indicator: indicator?.merge(other.indicator) ?? other.indicator, + animated: animated?.merge(other.animated) ?? other.animated, + ); + } + + /// The list of properties that constitute the state of this [CheckboxSpecAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [CheckboxSpecAttribute] instances for equality. + @override + List get props => [ + container, + indicator, + animated, + ]; +} + +/// Utility class for configuring [CheckboxSpecAttribute] properties. +/// +/// This class provides methods to set individual properties of a [CheckboxSpecAttribute]. +/// Use the methods of this class to configure specific properties of a [CheckboxSpecAttribute]. +base class CheckboxSpecUtility + extends SpecUtility { + /// Utility for defining [CheckboxSpecAttribute.container] + late final container = BoxSpecUtility((v) => only(container: v)); + + /// Utility for defining [CheckboxSpecAttribute.indicator] + late final indicator = IconSpecUtility((v) => only(indicator: v)); + + /// Utility for defining [CheckboxSpecAttribute.animated] + late final animated = AnimatedUtility((v) => only(animated: v)); + + CheckboxSpecUtility(super.builder); + + static final self = CheckboxSpecUtility((v) => v); + + /// Returns a new [CheckboxSpecAttribute] with the specified properties. + @override + T only({ + BoxSpecAttribute? container, + IconSpecAttribute? indicator, + AnimatedDataDto? animated, + }) { + return builder(CheckboxSpecAttribute( + container: container, + indicator: indicator, + animated: animated, + )); + } +} + +/// A tween that interpolates between two [CheckboxSpec] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [CheckboxSpec] specifications. +class CheckboxSpecTween extends Tween { + CheckboxSpecTween({ + super.begin, + super.end, + }); + + @override + CheckboxSpec lerp(double t) { + if (begin == null && end == null) return const CheckboxSpec(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} diff --git a/packages/remix/lib/components/checkbox/checkbox_style.dart b/packages/remix/lib/components/checkbox/checkbox_style.dart new file mode 100644 index 000000000..04776a86f --- /dev/null +++ b/packages/remix/lib/components/checkbox/checkbox_style.dart @@ -0,0 +1,120 @@ +// ignore_for_file: camel_case_types + +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/checkbox/checkbox_spec.dart'; +import 'package:remix/components/checkbox/checkbox_variants.dart'; +import 'package:remix/helpers/utility_extension.dart'; +import 'package:remix/tokens/remix_tokens.dart'; + +final _util = CheckboxSpecUtility.self; +final _container = _util.container; +final _indicator = _util.indicator; + +Style get _baseStyle => Style( + _container.borderRadius(4), + ); + +Style get _onDisabledForeground => Style( + $on.disabled( + _indicator.color.ref($rx.color.neutralAlpha(7)), + ), + ); + +Style get _solidVariant => Style( + _container.color.ref($rx.color.accent()), + _indicator.color.ref($rx.color.white()), + $on.hover( + _container.color.ref($rx.color.accent(10)), + ), + $on.disabled( + _container.color.ref($rx.color.neutralAlpha(3)), + ), + ); + +Style get _softVariant => Style( + _container.color.ref($rx.color.accentAlpha(3)), + _indicator.color.ref($rx.color.accentAlpha(11)), + $on.hover( + _container.color.ref($rx.color.accentAlpha(4)), + ), + $on.disabled( + _container.color.ref($rx.color.neutralAlpha(3)), + ), + ); +Style get _outlineVariant => Style( + _container.color(Colors.transparent), + _container.border.color.ref($rx.color.accentAlpha(8)), + _container.border.width(1.5), + _indicator.color.ref($rx.color.accentAlpha(11)), + $on.hover( + _container.color.ref($rx.color.accentAlpha(2)), + ), + $on.disabled( + _container.border.color.ref($rx.color.neutralAlpha(8)), + _container.color.transparent(), + ), + ); + +Style get _surfaceVariant => Style( + _outlineVariant(), + _container.color.ref($rx.color.accentAlpha(3)), + $on.hover( + _container.color.ref($rx.color.accentAlpha(4)), + _container.border.color.ref($rx.color.accentAlpha(8)), + ), + $on.disabled( + _container.color.ref($rx.color.neutralAlpha(2)), + ), + ); + +final _ghostVariant = Style( + _container.border.style.none(), + _container.color(Colors.transparent), + _indicator.color.ref($rx.color.accentAlpha(11)), + $on.hover( + _container.color.ref($rx.color.accentAlpha(3)), + ), +); + +Style get _disabledVariant => Style( + _container.color.ref($rx.color.neutralAlpha(3)), + _container.border.color.ref($rx.color.neutralAlpha(5)), + _indicator.color.ref($rx.color.neutralAlpha(7)), + ); + +Style get _smallVariant => Style( + _container.size(16), + _indicator.size(12), + ); + +Style get _mediumVariant => Style( + _container.size(20), + _indicator.size(16), + ); + +Style get _largeVariant => Style( + _container.size(24), + _indicator.size(20), + ); + +Style buildDefaultCheckboxStyle() { + return Style( + _baseStyle(), + + /// Size Variants + CheckboxSize.small(_smallVariant()), + CheckboxSize.medium(_mediumVariant()), + CheckboxSize.large(_largeVariant()), + + _onDisabledForeground(), + + // State variants + CheckboxVariant.solid(_solidVariant()), + CheckboxVariant.soft(_softVariant()), + CheckboxVariant.surface(_surfaceVariant()), + CheckboxVariant.outline(_outlineVariant()), + CheckboxVariant.ghost(_ghostVariant()), + $on.disabled(_disabledVariant()), + ); +} diff --git a/packages/remix/lib/components/checkbox/checkbox_variants.dart b/packages/remix/lib/components/checkbox/checkbox_variants.dart new file mode 100644 index 000000000..d3f84d275 --- /dev/null +++ b/packages/remix/lib/components/checkbox/checkbox_variants.dart @@ -0,0 +1,40 @@ +import 'package:remix/helpers/variant.dart'; + +abstract interface class ICheckboxVariant extends RemixVariant { + const ICheckboxVariant(String name) : super('checkbox.$name'); +} + +class CheckboxStatus extends ICheckboxVariant { + const CheckboxStatus._(String name) : super('status.$name'); + + static const checked = CheckboxStatus._('checked'); + static const unchecked = CheckboxStatus._('unchecked'); +} + +class CheckboxVariant extends ICheckboxVariant { + const CheckboxVariant(String name) : super('variant.$name'); + + static const solid = CheckboxVariant('solid'); + static const soft = CheckboxVariant('soft'); + static const surface = CheckboxVariant('surface'); + static const outline = CheckboxVariant('outline'); + static const ghost = CheckboxVariant('ghost'); + + static List get values => [ + solid, + soft, + surface, + outline, + ghost, + ]; +} + +class CheckboxSize extends ICheckboxVariant { + const CheckboxSize(String name) : super('size.$name'); + + static const small = CheckboxSize('small'); + static const medium = CheckboxSize('medium'); + static const large = CheckboxSize('large'); + + static List get values => [small, medium, large]; +} diff --git a/packages/remix/lib/components/checkbox/checkbox_widget.dart b/packages/remix/lib/components/checkbox/checkbox_widget.dart new file mode 100644 index 000000000..444754993 --- /dev/null +++ b/packages/remix/lib/components/checkbox/checkbox_widget.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/checkbox/checkbox_spec.dart'; +import 'package:remix/components/checkbox/checkbox_style.dart'; +import 'package:remix/components/checkbox/checkbox_variants.dart'; + +class RxCheckbox extends StatelessWidget { + const RxCheckbox({ + super.key, + this.disabled = false, + this.value = false, + this.onChanged, + this.iconChecked = Icons.check_rounded, + this.iconUnchecked, + this.style, + this.size = CheckboxSize.medium, + this.variant = CheckboxVariant.solid, + }); + + final bool disabled; + final bool value; + final IconData iconChecked; + final IconData? iconUnchecked; + final ValueChanged? onChanged; + + /// Additional custom styling for the button. + /// + /// This allows you to override or extend the default button styling. + final Style? style; + + final CheckboxSize size; + final CheckboxVariant variant; + + void _handleOnPress() => onChanged?.call(!value); + + Style _buildStyle() { + return buildDefaultCheckboxStyle().merge(style).applyVariants([ + size, + variant, + value ? CheckboxStatus.checked : CheckboxStatus.unchecked + ]).animate(); + } + + @override + Widget build(BuildContext context) { + return Pressable( + onPress: disabled ? null : _handleOnPress, + enabled: !disabled, + child: SpecBuilder( + style: _buildStyle(), + builder: (context) { + final spec = CheckboxSpec.of(context); + + final ContainerWidget = spec.container; + final IconWidget = spec.indicator; + + return ContainerWidget( + child: IconWidget( + value ? iconChecked : iconUnchecked, + ), + ); + }, + ), + ); + } +} diff --git a/packages/remix/lib/components/checkbox_group/checkbox_group.dart b/packages/remix/lib/components/checkbox_group/checkbox_group.dart new file mode 100644 index 000000000..28b9c3ba1 --- /dev/null +++ b/packages/remix/lib/components/checkbox_group/checkbox_group.dart @@ -0,0 +1,72 @@ +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/checkbox/checkbox_variants.dart'; +import 'package:remix/components/checkbox/checkbox_widget.dart'; + +class RxCheckboxGroup extends StatefulWidget { + const RxCheckboxGroup({ + super.key, + required this.items, + this.defaultValue = const [], + this.onValueChange, + this.size = CheckboxSize.medium, + this.variant = CheckboxVariant.solid, + }); + + final List items; + final List defaultValue; + final ValueChanged>? onValueChange; + final CheckboxSize size; + final CheckboxVariant variant; + + @override + _RxCheckboxGroupState createState() => _RxCheckboxGroupState(); +} + +class _RxCheckboxGroupState extends State { + late List _selectedValues; + + @override + void initState() { + super.initState(); + _selectedValues = List.from(widget.defaultValue); + } + + void _handleValueChange(String value, bool isSelected) { + setState(() { + if (isSelected) { + _selectedValues.add(value); + } else { + _selectedValues.remove(value); + } + }); + + widget.onValueChange?.call(_selectedValues); + } + + @override + Widget build(BuildContext context) { + return Column( + children: widget.items.map((item) { + final isSelected = _selectedValues.contains(item.value); + return RxCheckbox( + value: isSelected, + onChanged: (isSelected) => _handleValueChange(item.value, isSelected), + size: widget.size, + variant: widget.variant, + style: item.style, + ); + }).toList(), + ); + } +} + +class RxCheckboxItem { + const RxCheckboxItem({ + required this.value, + this.style, + }); + + final String value; + final Style? style; +} diff --git a/packages/remix/lib/components/context.md b/packages/remix/lib/components/context.md new file mode 100644 index 000000000..e69de29bb diff --git a/packages/remix/lib/components/progress/progress_spec.dart b/packages/remix/lib/components/progress/progress_spec.dart new file mode 100644 index 000000000..d087d7016 --- /dev/null +++ b/packages/remix/lib/components/progress/progress_spec.dart @@ -0,0 +1,26 @@ +import 'package:flutter/widgets.dart'; +import 'package:mix/mix.dart'; +import 'package:mix_annotations/mix_annotations.dart'; + +part 'progress_spec.g.dart'; + +@MixableSpec() +base class ProgressSpec extends Spec with _$ProgressSpec { + final BoxSpec container; + final BoxSpec track; + final BoxSpec fill; + + /// {@macro progress_spec_of} + static const of = _$ProgressSpec.of; + + static const from = _$ProgressSpec.from; + + const ProgressSpec({ + BoxSpec? container, + BoxSpec? track, + BoxSpec? fill, + super.animated, + }) : container = container ?? const BoxSpec(), + track = track ?? const BoxSpec(), + fill = fill ?? const BoxSpec(); +} diff --git a/packages/remix/lib/components/progress/progress_spec.g.dart b/packages/remix/lib/components/progress/progress_spec.g.dart new file mode 100644 index 000000000..6d66148d2 --- /dev/null +++ b/packages/remix/lib/components/progress/progress_spec.g.dart @@ -0,0 +1,223 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'progress_spec.dart'; + +// ************************************************************************** +// MixableSpecGenerator +// ************************************************************************** + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$ProgressSpec on Spec { + static ProgressSpec from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? + const ProgressSpec(); + } + + /// {@template progress_spec_of} + /// Retrieves the [ProgressSpec] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [ProgressSpec] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [ProgressSpec]. + /// + /// Example: + /// + /// ```dart + /// final progressSpec = ProgressSpec.of(context); + /// ``` + /// {@endtemplate} + static ProgressSpec of(BuildContext context) { + return _$ProgressSpec.from(Mix.of(context)); + } + + /// Creates a copy of this [ProgressSpec] but with the given fields + /// replaced with the new values. + @override + ProgressSpec copyWith({ + BoxSpec? container, + BoxSpec? track, + BoxSpec? fill, + AnimatedData? animated, + }) { + return ProgressSpec( + container: container ?? _$this.container, + track: track ?? _$this.track, + fill: fill ?? _$this.fill, + animated: animated ?? _$this.animated, + ); + } + + /// Linearly interpolates between this [ProgressSpec] and another [ProgressSpec] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [ProgressSpec] is returned. When [t] is 1.0, the [other] [ProgressSpec] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [ProgressSpec] is returned. + /// + /// If [other] is null, this method returns the current [ProgressSpec] instance. + /// + /// The interpolation is performed on each property of the [ProgressSpec] using the appropriate + /// interpolation method: + /// + /// - [BoxSpec.lerp] for [container] and [track] and [fill]. + + /// For [animated], the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [ProgressSpec] is used. Otherwise, the value + /// from the [other] [ProgressSpec] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [ProgressSpec] configurations. + @override + ProgressSpec lerp(ProgressSpec? other, double t) { + if (other == null) return _$this; + + return ProgressSpec( + container: _$this.container.lerp(other.container, t), + track: _$this.track.lerp(other.track, t), + fill: _$this.fill.lerp(other.fill, t), + animated: t < 0.5 ? _$this.animated : other.animated, + ); + } + + /// The list of properties that constitute the state of this [ProgressSpec]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [ProgressSpec] instances for equality. + @override + List get props => [ + _$this.container, + _$this.track, + _$this.fill, + _$this.animated, + ]; + + ProgressSpec get _$this => this as ProgressSpec; +} + +/// Represents the attributes of a [ProgressSpec]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [ProgressSpec]. +/// +/// Use this class to configure the attributes of a [ProgressSpec] and pass it to +/// the [ProgressSpec] constructor. +final class ProgressSpecAttribute extends SpecAttribute { + final BoxSpecAttribute? container; + final BoxSpecAttribute? track; + final BoxSpecAttribute? fill; + + const ProgressSpecAttribute({ + this.container, + this.track, + this.fill, + super.animated, + }); + + /// Resolves to [ProgressSpec] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final progressSpec = ProgressSpecAttribute(...).resolve(mix); + /// ``` + @override + ProgressSpec resolve(MixData mix) { + return ProgressSpec( + container: container?.resolve(mix), + track: track?.resolve(mix), + fill: fill?.resolve(mix), + animated: animated?.resolve(mix) ?? mix.animation, + ); + } + + /// Merges the properties of this [ProgressSpecAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [ProgressSpecAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + ProgressSpecAttribute merge(covariant ProgressSpecAttribute? other) { + if (other == null) return this; + + return ProgressSpecAttribute( + container: container?.merge(other.container) ?? other.container, + track: track?.merge(other.track) ?? other.track, + fill: fill?.merge(other.fill) ?? other.fill, + animated: animated?.merge(other.animated) ?? other.animated, + ); + } + + /// The list of properties that constitute the state of this [ProgressSpecAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [ProgressSpecAttribute] instances for equality. + @override + List get props => [ + container, + track, + fill, + animated, + ]; +} + +/// Utility class for configuring [ProgressSpecAttribute] properties. +/// +/// This class provides methods to set individual properties of a [ProgressSpecAttribute]. +/// Use the methods of this class to configure specific properties of a [ProgressSpecAttribute]. +base class ProgressSpecUtility + extends SpecUtility { + /// Utility for defining [ProgressSpecAttribute.container] + late final container = BoxSpecUtility((v) => only(container: v)); + + /// Utility for defining [ProgressSpecAttribute.track] + late final track = BoxSpecUtility((v) => only(track: v)); + + /// Utility for defining [ProgressSpecAttribute.fill] + late final fill = BoxSpecUtility((v) => only(fill: v)); + + /// Utility for defining [ProgressSpecAttribute.animated] + late final animated = AnimatedUtility((v) => only(animated: v)); + + ProgressSpecUtility(super.builder); + + static final self = ProgressSpecUtility((v) => v); + + /// Returns a new [ProgressSpecAttribute] with the specified properties. + @override + T only({ + BoxSpecAttribute? container, + BoxSpecAttribute? track, + BoxSpecAttribute? fill, + AnimatedDataDto? animated, + }) { + return builder(ProgressSpecAttribute( + container: container, + track: track, + fill: fill, + animated: animated, + )); + } +} + +/// A tween that interpolates between two [ProgressSpec] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [ProgressSpec] specifications. +class ProgressSpecTween extends Tween { + ProgressSpecTween({ + super.begin, + super.end, + }); + + @override + ProgressSpec lerp(double t) { + if (begin == null && end == null) return const ProgressSpec(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} diff --git a/packages/remix/lib/components/progress/progress_style.dart b/packages/remix/lib/components/progress/progress_style.dart new file mode 100644 index 000000000..572ab6a71 --- /dev/null +++ b/packages/remix/lib/components/progress/progress_style.dart @@ -0,0 +1,87 @@ +// ignore_for_file: camel_case_types + +import 'package:mix/mix.dart'; +import 'package:remix/components/progress/progress_spec.dart'; +import 'package:remix/components/progress/progress_variants.dart'; +import 'package:remix/tokens/remix_tokens.dart'; + +final _progress = ProgressSpecUtility.self; +final _container = _progress.container; +final _track = _progress.track; +final _fill = _progress.fill; + +Style get _baseStyle => Style( + _container.borderRadius(99), + _track.color.ref($rx.color.neutralAlpha(3)), + _fill.color.ref($rx.color.accent()), + ); + +final _smallVariant = Style( + _container.height(4), +); + +final _mediumVariant = Style( + _container.height(8), +); + +final _largeVariant = Style( + _container.height(12), +); + +final _classicVariant = Style( + _track.color.ref($rx.color.neutralAlpha(3)), + _fill.color.ref($rx.color.accent()), +); + +final _surfaceVariant = Style( + _track.color.ref($rx.color.neutralAlpha(2)), + _fill.color.ref($rx.color.accent()), +); + +final _softVariant = Style( + _track.color.ref($rx.color.accentAlpha(3)), + _fill.color.ref($rx.color.accent()), +); + +final _noneRadiusVariant = Style( + _container.borderRadius(0), +); + +final _smallRadiusVariant = Style( + _container.borderRadius(4), +); + +final _mediumRadiusVariant = Style( + _container.borderRadius(8), +); + +final _largeRadiusVariant = Style( + _container.borderRadius(12), +); + +final _fullRadiusVariant = Style( + _container.borderRadius(99), +); + +Style buildDefaultProgressStyle() { + return Style( + _baseStyle(), + + /// Size Variants + ProgressSize.small(_smallVariant()), + ProgressSize.medium(_mediumVariant()), + ProgressSize.large(_largeVariant()), + + // Type variants + ProgressVariant.classic(_classicVariant()), + ProgressVariant.surface(_surfaceVariant()), + ProgressVariant.soft(_softVariant()), + + // Radius variants + ProgressRadius.none(_noneRadiusVariant()), + ProgressRadius.small(_smallRadiusVariant()), + ProgressRadius.medium(_mediumRadiusVariant()), + ProgressRadius.large(_largeRadiusVariant()), + ProgressRadius.full(_fullRadiusVariant()), + ); +} diff --git a/packages/remix/lib/components/progress/progress_variants.dart b/packages/remix/lib/components/progress/progress_variants.dart new file mode 100644 index 000000000..45026588b --- /dev/null +++ b/packages/remix/lib/components/progress/progress_variants.dart @@ -0,0 +1,37 @@ +import 'package:mix/mix.dart'; + +abstract interface class IProgressVariant extends Variant { + const IProgressVariant(super.name); +} + +class ProgressVariant extends IProgressVariant { + const ProgressVariant(super.name); + + static const classic = ProgressVariant('remix.progress.classic'); + static const surface = ProgressVariant('remix.progress.surface'); + static const soft = ProgressVariant('remix.progress.soft'); + + static List get values => [classic, surface, soft]; +} + +class ProgressSize extends IProgressVariant { + const ProgressSize(super.name); + + static const small = ProgressSize('remix.progress.small'); + static const medium = ProgressSize('remix.progress.medium'); + static const large = ProgressSize('remix.progress.large'); + + static List get values => [small, medium, large]; +} + +class ProgressRadius extends IProgressVariant { + const ProgressRadius(super.name); + + static const none = ProgressRadius('remix.progress.none'); + static const small = ProgressRadius('remix.progress.small'); + static const medium = ProgressRadius('remix.progress.medium'); + static const large = ProgressRadius('remix.progress.large'); + static const full = ProgressRadius('remix.progress.full'); + + static List get values => [none, small, medium, large, full]; +} diff --git a/packages/remix/lib/components/progress/progress_widget.dart b/packages/remix/lib/components/progress/progress_widget.dart new file mode 100644 index 000000000..550d606e8 --- /dev/null +++ b/packages/remix/lib/components/progress/progress_widget.dart @@ -0,0 +1,55 @@ +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/progress/progress_spec.dart'; +import 'package:remix/components/progress/progress_style.dart'; +import 'package:remix/components/progress/progress_variants.dart'; + +class RxProgress extends StatelessWidget { + const RxProgress({ + super.key, + this.value = 0.0, + this.size = ProgressSize.medium, + this.variant = ProgressVariant.surface, + this.highContrast = false, + this.radius = ProgressRadius.none, + this.duration, + }); + + final double value; + final ProgressSize size; + final ProgressVariant variant; + + final bool highContrast; + final ProgressRadius radius; + final Duration? duration; + + Style _buildStyle() { + return buildDefaultProgressStyle().applyVariants( + [size, variant, radius], + ).animate(); + } + + @override + Widget build(BuildContext context) { + return SpecBuilder( + style: _buildStyle(), + builder: (context) { + final spec = ProgressSpec.of(context); + + final FillWidget = spec.fill.copyWith( + width: value * 100, + ); + + return spec.container( + child: Stack( + fit: StackFit.expand, + children: [ + spec.track(), + FillWidget(), + ], + ), + ); + }, + ); + } +} diff --git a/packages/remix/lib/components/radio/radio_spec.dart b/packages/remix/lib/components/radio/radio_spec.dart new file mode 100644 index 000000000..9da3047c5 --- /dev/null +++ b/packages/remix/lib/components/radio/radio_spec.dart @@ -0,0 +1,23 @@ +import 'package:flutter/cupertino.dart'; +import 'package:mix/mix.dart'; +import 'package:mix_annotations/mix_annotations.dart'; + +part 'radio_spec.g.dart'; + +@MixableSpec() +base class RadioSpec extends Spec with _$RadioSpec { + final BoxSpec container; + final BoxSpec indicator; + + /// {@macro radio_spec_of} + static const of = _$RadioSpec.of; + + static const from = _$RadioSpec.from; + + const RadioSpec({ + BoxSpec? container, + BoxSpec? indicator, + super.animated, + }) : container = container ?? const BoxSpec(), + indicator = indicator ?? const BoxSpec(); +} diff --git a/packages/remix/lib/components/radio/radio_spec.g.dart b/packages/remix/lib/components/radio/radio_spec.g.dart new file mode 100644 index 000000000..72e145e23 --- /dev/null +++ b/packages/remix/lib/components/radio/radio_spec.g.dart @@ -0,0 +1,209 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'radio_spec.dart'; + +// ************************************************************************** +// MixableSpecGenerator +// ************************************************************************** + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$RadioSpec on Spec { + static RadioSpec from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? + const RadioSpec(); + } + + /// {@template radio_spec_of} + /// Retrieves the [RadioSpec] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [RadioSpec] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [RadioSpec]. + /// + /// Example: + /// + /// ```dart + /// final radioSpec = RadioSpec.of(context); + /// ``` + /// {@endtemplate} + static RadioSpec of(BuildContext context) { + return _$RadioSpec.from(Mix.of(context)); + } + + /// Creates a copy of this [RadioSpec] but with the given fields + /// replaced with the new values. + @override + RadioSpec copyWith({ + BoxSpec? container, + BoxSpec? indicator, + AnimatedData? animated, + }) { + return RadioSpec( + container: container ?? _$this.container, + indicator: indicator ?? _$this.indicator, + animated: animated ?? _$this.animated, + ); + } + + /// Linearly interpolates between this [RadioSpec] and another [RadioSpec] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [RadioSpec] is returned. When [t] is 1.0, the [other] [RadioSpec] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [RadioSpec] is returned. + /// + /// If [other] is null, this method returns the current [RadioSpec] instance. + /// + /// The interpolation is performed on each property of the [RadioSpec] using the appropriate + /// interpolation method: + /// + /// - [BoxSpec.lerp] for [container] and [indicator]. + + /// For [animated], the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [RadioSpec] is used. Otherwise, the value + /// from the [other] [RadioSpec] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [RadioSpec] configurations. + @override + RadioSpec lerp(RadioSpec? other, double t) { + if (other == null) return _$this; + + return RadioSpec( + container: _$this.container.lerp(other.container, t), + indicator: _$this.indicator.lerp(other.indicator, t), + animated: t < 0.5 ? _$this.animated : other.animated, + ); + } + + /// The list of properties that constitute the state of this [RadioSpec]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [RadioSpec] instances for equality. + @override + List get props => [ + _$this.container, + _$this.indicator, + _$this.animated, + ]; + + RadioSpec get _$this => this as RadioSpec; +} + +/// Represents the attributes of a [RadioSpec]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [RadioSpec]. +/// +/// Use this class to configure the attributes of a [RadioSpec] and pass it to +/// the [RadioSpec] constructor. +final class RadioSpecAttribute extends SpecAttribute { + final BoxSpecAttribute? container; + final BoxSpecAttribute? indicator; + + const RadioSpecAttribute({ + this.container, + this.indicator, + super.animated, + }); + + /// Resolves to [RadioSpec] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final radioSpec = RadioSpecAttribute(...).resolve(mix); + /// ``` + @override + RadioSpec resolve(MixData mix) { + return RadioSpec( + container: container?.resolve(mix), + indicator: indicator?.resolve(mix), + animated: animated?.resolve(mix) ?? mix.animation, + ); + } + + /// Merges the properties of this [RadioSpecAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [RadioSpecAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + RadioSpecAttribute merge(covariant RadioSpecAttribute? other) { + if (other == null) return this; + + return RadioSpecAttribute( + container: container?.merge(other.container) ?? other.container, + indicator: indicator?.merge(other.indicator) ?? other.indicator, + animated: animated?.merge(other.animated) ?? other.animated, + ); + } + + /// The list of properties that constitute the state of this [RadioSpecAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [RadioSpecAttribute] instances for equality. + @override + List get props => [ + container, + indicator, + animated, + ]; +} + +/// Utility class for configuring [RadioSpecAttribute] properties. +/// +/// This class provides methods to set individual properties of a [RadioSpecAttribute]. +/// Use the methods of this class to configure specific properties of a [RadioSpecAttribute]. +base class RadioSpecUtility + extends SpecUtility { + /// Utility for defining [RadioSpecAttribute.container] + late final container = BoxSpecUtility((v) => only(container: v)); + + /// Utility for defining [RadioSpecAttribute.indicator] + late final indicator = BoxSpecUtility((v) => only(indicator: v)); + + /// Utility for defining [RadioSpecAttribute.animated] + late final animated = AnimatedUtility((v) => only(animated: v)); + + RadioSpecUtility(super.builder); + + static final self = RadioSpecUtility((v) => v); + + /// Returns a new [RadioSpecAttribute] with the specified properties. + @override + T only({ + BoxSpecAttribute? container, + BoxSpecAttribute? indicator, + AnimatedDataDto? animated, + }) { + return builder(RadioSpecAttribute( + container: container, + indicator: indicator, + animated: animated, + )); + } +} + +/// A tween that interpolates between two [RadioSpec] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [RadioSpec] specifications. +class RadioSpecTween extends Tween { + RadioSpecTween({ + super.begin, + super.end, + }); + + @override + RadioSpec lerp(double t) { + if (begin == null && end == null) return const RadioSpec(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} diff --git a/packages/remix/lib/components/radio/radio_style.dart b/packages/remix/lib/components/radio/radio_style.dart new file mode 100644 index 000000000..7dc526d47 --- /dev/null +++ b/packages/remix/lib/components/radio/radio_style.dart @@ -0,0 +1,114 @@ +// ignore_for_file: camel_case_types + +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/radio/radio_spec.dart'; +import 'package:remix/components/radio/radio_variants.dart'; +import 'package:remix/helpers/utility_extension.dart'; +import 'package:remix/tokens/remix_tokens.dart'; + +final _radio = RadioSpecUtility.self; +final _container = _radio.container; +final _indicator = _radio.indicator; + +Style get _baseStyle => Style( + _container.borderRadius(99), + _container.alignment.center(), + _indicator.borderRadius(99), + ); + +Style get _solidVariant => Style( + _container.color.ref($rx.color.accent()), + _indicator.color.ref($rx.color.white()), + $on.hover( + _container.color.ref($rx.color.accent(10)), + ), + $on.disabled( + _container.color.ref($rx.color.neutralAlpha(3)), + ), + ); + +Style get _softVariant => Style( + _container.color.ref($rx.color.accentAlpha(3)), + _indicator.color.ref($rx.color.accentAlpha(11)), + $on.hover( + _container.color.ref($rx.color.accentAlpha(4)), + ), + $on.disabled( + _container.color.ref($rx.color.neutralAlpha(3)), + ), + ); + +Style get _outlineVariant => Style( + _container.color(Colors.transparent), + _container.border.color.ref($rx.color.accentAlpha(8)), + _container.border.width(1.5), + _indicator.color.ref($rx.color.accentAlpha(11)), + $on.hover( + _container.color.ref($rx.color.accentAlpha(2)), + ), + $on.disabled( + _container.border.color.ref($rx.color.neutralAlpha(8)), + _container.color.transparent(), + ), + ); + +Style get _surfaceVariant => Style( + _outlineVariant(), + _container.color.ref($rx.color.accentAlpha(3)), + $on.hover( + _container.color.ref($rx.color.accentAlpha(4)), + _container.border.color.ref($rx.color.accentAlpha(8)), + ), + $on.disabled( + _container.color.ref($rx.color.neutralAlpha(3)), + ), + ); + +Style get _ghostVariant => Style( + _container.border.style.none(), + _container.color(Colors.transparent), + _indicator.color.ref($rx.color.accentAlpha(11)), + $on.hover( + _container.color.ref($rx.color.accentAlpha(3)), + ), + ); +Style get _smallVariant => Style( + _container.size(16), + _indicator.size(8), + ); + +Style get _mediumVariant => Style( + _container.size(20), + _indicator.size(10), + ); + +Style get _largeVariant => Style( + _container.size(24), + _indicator.size(12), + ); + +Style get _disabledVariant => Style( + _container.color.ref($rx.color.neutralAlpha(3)), + _container.border.color.ref($rx.color.neutralAlpha(5)), + _indicator.color.ref($rx.color.neutralAlpha(7)), + ); + +Style buildDefaultRadioStyle() { + return Style( + _baseStyle(), + + /// Size Variants + RadioSize.small(_smallVariant()), + RadioSize.medium(_mediumVariant()), + RadioSize.large(_largeVariant()), + + // State variants + RadioVariant.solid(_solidVariant()), + RadioVariant.soft(_softVariant()), + RadioVariant.outline(_outlineVariant()), + RadioVariant.surface(_surfaceVariant()), + RadioVariant.ghost(_ghostVariant()), + $on.disabled(_disabledVariant()), + ); +} diff --git a/packages/remix/lib/components/radio/radio_variants.dart b/packages/remix/lib/components/radio/radio_variants.dart new file mode 100644 index 000000000..fb2f3991b --- /dev/null +++ b/packages/remix/lib/components/radio/radio_variants.dart @@ -0,0 +1,40 @@ +import 'package:remix/helpers/variant.dart'; + +abstract interface class IRadioVariant extends RemixVariant { + const IRadioVariant(String name) : super('radio.$name'); +} + +class RadioStatus extends IRadioVariant { + const RadioStatus(String name) : super('status.$name'); + + static const checked = RadioStatus('checked'); + static const unchecked = RadioStatus('unchecked'); +} + +class RadioVariant extends IRadioVariant { + const RadioVariant(String name) : super('variant.$name'); + + static const solid = RadioVariant('solid'); + static const soft = RadioVariant('soft'); + static const surface = RadioVariant('surface'); + static const outline = RadioVariant('outline'); + static const ghost = RadioVariant('ghost'); + + static List get values => [ + solid, + soft, + surface, + outline, + ghost, + ]; +} + +class RadioSize extends IRadioVariant { + const RadioSize(String name) : super('size.$name'); + + static const small = RadioSize('small'); + static const medium = RadioSize('medium'); + static const large = RadioSize('large'); + + static List get values => [small, medium, large]; +} diff --git a/packages/remix/lib/components/radio/radio_widget.dart b/packages/remix/lib/components/radio/radio_widget.dart new file mode 100644 index 000000000..47ce07722 --- /dev/null +++ b/packages/remix/lib/components/radio/radio_widget.dart @@ -0,0 +1,53 @@ +import 'package:flutter/widgets.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/radio/radio_spec.dart'; +import 'package:remix/components/radio/radio_style.dart'; +import 'package:remix/components/radio/radio_variants.dart'; + +class RxRadio extends StatelessWidget { + const RxRadio({ + super.key, + required this.value, + required this.onChanged, + this.variant = RadioVariant.solid, + this.size = RadioSize.medium, + this.disabled = false, + this.style, + }); + + final bool value; + final ValueChanged onChanged; + final RadioVariant variant; + final RadioSize size; + final Style? style; + final bool disabled; + + void _handleOnPress() => onChanged.call(!value); + + Style _buildStyle() { + return buildDefaultRadioStyle() + .merge(style) + .applyVariants([size, variant]).animate(); + } + + @override + Widget build(BuildContext context) { + return Pressable( + onPress: disabled ? null : _handleOnPress, + enabled: !disabled, + child: SpecBuilder( + style: _buildStyle(), + builder: (context) { + final spec = RadioSpec.of(context); + + final ContainerWidget = spec.container; + final IndicatorWidget = spec.indicator; + + return ContainerWidget( + child: value ? IndicatorWidget() : null, + ); + }, + ), + ); + } +} diff --git a/packages/remix/lib/components/spinner/spinner.style.dart b/packages/remix/lib/components/spinner/spinner.style.dart new file mode 100644 index 000000000..2e14e9800 --- /dev/null +++ b/packages/remix/lib/components/spinner/spinner.style.dart @@ -0,0 +1,34 @@ +import 'package:mix/mix.dart'; +import 'package:remix/components/spinner/spinner.variants.dart'; +import 'package:remix/components/spinner/spinner_spec.dart'; +import 'package:remix/tokens/remix_tokens.dart'; + +final _util = SpinnerSpecUtility.self; + +Style get _baseStyle => Style( + _util.color.ref($rx.color.accent()), + ); + +Style get _smallVariant => Style( + _util.size(16), + _util.strokeWidth(1), + ); + +Style get _mediumVariant => Style( + _util.size(24), + _util.strokeWidth(1.5), + ); + +Style get _largeVariant => Style( + _util.size(32), + _util.strokeWidth(2), + ); + +Style buildSpinnerStyle() { + return Style( + _baseStyle(), + SpinnerSize.small(_smallVariant()), + SpinnerSize.medium(_mediumVariant()), + SpinnerSize.large(_largeVariant()), + ); +} diff --git a/packages/remix/lib/components/spinner/spinner.variants.dart b/packages/remix/lib/components/spinner/spinner.variants.dart new file mode 100644 index 000000000..918d07336 --- /dev/null +++ b/packages/remix/lib/components/spinner/spinner.variants.dart @@ -0,0 +1,24 @@ +import 'package:remix/helpers/variant.dart'; + +interface class ISpinnerVariant extends RemixVariant { + const ISpinnerVariant(String name) : super('spinner.$name'); +} + +class SpinnerSize extends ISpinnerVariant { + const SpinnerSize(String name) : super('size.$name'); + + static const small = SpinnerSize('small'); + static const medium = SpinnerSize('medium'); + static const large = SpinnerSize('large'); + + static List get values => [small, medium, large]; +} + +class SpinnerVariant extends ISpinnerVariant { + const SpinnerVariant(String name) : super('variant.$name'); + + static const solid = SpinnerVariant('solid'); + static const dotted = SpinnerVariant('dotted'); + + static List get values => [dotted, solid]; +} diff --git a/packages/remix/lib/components/spinner/spinner_painter.dart b/packages/remix/lib/components/spinner/spinner_painter.dart new file mode 100644 index 000000000..41bde9267 --- /dev/null +++ b/packages/remix/lib/components/spinner/spinner_painter.dart @@ -0,0 +1,131 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +abstract interface class SpinnerPainter extends CustomPainter { + final Animation animation; + final double strokeWidth; + final Color color; + + SpinnerPainter({ + required this.animation, + required this.strokeWidth, + required this.color, + }) : super(repaint: animation); +} + +class DottedSpinnerPainter extends SpinnerPainter { + DottedSpinnerPainter({ + required super.animation, + required super.strokeWidth, + required super.color, + }); + + @override + void paint(Canvas canvas, Size size) { + final specStrokeWidth = strokeWidth / 2; + + final paint = Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = 2 * specStrokeWidth; + + canvas.translate(size.width / 2, size.height / 2); + + final radius = min(size.width, size.height) / 2 - paint.strokeWidth; + const lines = 12; + const lineAngle = 2 * pi / lines; + + for (int i = 0; i < lines; i++) { + final angle = i * lineAngle; + final opacity = (lines - i + animation.value * lines) % lines / lines; + + paint.color = color.withOpacity(opacity); + + final lineHeight = radius * 0.45; + + canvas.drawLine( + Offset(radius * 0.9 * cos(angle), radius * 0.9 * sin(angle)), + Offset(lineHeight * cos(angle), lineHeight * sin(angle)), + paint, + ); + } + } + + @override + bool shouldRepaint(DottedSpinnerPainter oldDelegate) => true; +} + +class StrippedSpinnerPainter extends SpinnerPainter { + StrippedSpinnerPainter({ + required super.animation, + required super.strokeWidth, + required super.color, + }); + + @override + void paint(Canvas canvas, Size size) { + final specStrokeWidth = strokeWidth / 2; + + final paint = Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = 2 * specStrokeWidth; + + canvas.translate(size.width / 2, size.height / 2); + + final radius = min(size.width, size.height) / 2 - paint.strokeWidth; + const lines = 12; + const lineAngle = 2 * pi / lines; + + for (int i = 0; i < lines; i++) { + final angle = i * lineAngle; + final opacity = (lines - i + animation.value * lines) % lines / lines; + + paint.color = color.withOpacity(opacity); + + final lineHeight = radius * 0.8; + + canvas.drawLine( + Offset(radius * 0.9 * cos(angle), radius * 0.9 * sin(angle)), + Offset(lineHeight * cos(angle), lineHeight * sin(angle)), + paint, + ); + } + } + + @override + bool shouldRepaint(DottedSpinnerPainter oldDelegate) => true; +} + +class SolidSpinnerPainter extends SpinnerPainter { + SolidSpinnerPainter({ + required super.animation, + required super.strokeWidth, + required super.color, + }); + + @override + void paint(Canvas canvas, Size size) { + final specStrokeWidth = strokeWidth; + final paint = Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = 2 * specStrokeWidth + ..color = color; + + canvas.translate(size.width / 2, size.height / 2); + + final radius = min(size.width, size.height) / 2 - paint.strokeWidth; + const startAngle = pi / 3; + const sweepAngle = 2 * pi / 3; + + canvas.drawArc( + Rect.fromCircle(center: Offset.zero, radius: radius), + startAngle + animation.value * 2 * pi, + sweepAngle, + false, + paint, + ); + } + + @override + bool shouldRepaint(SolidSpinnerPainter oldDelegate) => true; +} diff --git a/packages/remix/lib/components/spinner/spinner_spec.dart b/packages/remix/lib/components/spinner/spinner_spec.dart new file mode 100644 index 000000000..bb47a05c8 --- /dev/null +++ b/packages/remix/lib/components/spinner/spinner_spec.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:mix_annotations/mix_annotations.dart'; +import 'package:remix/components/spinner/spinner_widget.dart'; + +part 'spinner_spec.g.dart'; + +enum SpinnerStyle { + solid, + dotted, +} + +@MixableSpec() +final class SpinnerSpec extends Spec with _$SpinnerSpec { + /// Size of the spinner + final double size; + + /// Width of the stroke of the line + /// Needs to be a double between 0 and 1 + final double? strokeWidth; + + /// Color of the spinner line + final Color color; + + /// Duration of a full cycle of spin + final Duration duration; + + final SpinnerStyle style; + + static const of = _$SpinnerSpec.of; + static const from = _$SpinnerSpec.from; + + const SpinnerSpec({ + double? size, + this.strokeWidth, + Color? color, + Duration? duration, + SpinnerStyle? style, + super.animated, + }) : size = size ?? 24, + color = color ?? Colors.white, + style = style ?? SpinnerStyle.solid, + duration = duration ?? const Duration(milliseconds: 500); + + Widget call() => RxSpinnerSpecWidget(spec: this); +} + +final class SpinnerStyleUtility + extends ScalarUtility { + SpinnerStyleUtility(super.builder); + + T dotted() => call(SpinnerStyle.dotted); + T solid() => call(SpinnerStyle.solid); +} diff --git a/packages/remix/lib/components/spinner/spinner_spec.g.dart b/packages/remix/lib/components/spinner/spinner_spec.g.dart new file mode 100644 index 000000000..7392543ad --- /dev/null +++ b/packages/remix/lib/components/spinner/spinner_spec.g.dart @@ -0,0 +1,253 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'spinner_spec.dart'; + +// ************************************************************************** +// MixableSpecGenerator +// ************************************************************************** + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$SpinnerSpec on Spec { + static SpinnerSpec from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? + const SpinnerSpec(); + } + + /// {@template spinner_spec_of} + /// Retrieves the [SpinnerSpec] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [SpinnerSpec] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [SpinnerSpec]. + /// + /// Example: + /// + /// ```dart + /// final spinnerSpec = SpinnerSpec.of(context); + /// ``` + /// {@endtemplate} + static SpinnerSpec of(BuildContext context) { + return _$SpinnerSpec.from(Mix.of(context)); + } + + /// Creates a copy of this [SpinnerSpec] but with the given fields + /// replaced with the new values. + @override + SpinnerSpec copyWith({ + double? size, + double? strokeWidth, + Color? color, + Duration? duration, + SpinnerStyle? style, + AnimatedData? animated, + }) { + return SpinnerSpec( + size: size ?? _$this.size, + strokeWidth: strokeWidth ?? _$this.strokeWidth, + color: color ?? _$this.color, + duration: duration ?? _$this.duration, + style: style ?? _$this.style, + animated: animated ?? _$this.animated, + ); + } + + /// Linearly interpolates between this [SpinnerSpec] and another [SpinnerSpec] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [SpinnerSpec] is returned. When [t] is 1.0, the [other] [SpinnerSpec] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [SpinnerSpec] is returned. + /// + /// If [other] is null, this method returns the current [SpinnerSpec] instance. + /// + /// The interpolation is performed on each property of the [SpinnerSpec] using the appropriate + /// interpolation method: + /// + /// - [MixHelpers.lerpDouble] for [size] and [strokeWidth]. + /// - [Color.lerp] for [color]. + + /// For [duration] and [style] and [animated], the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [SpinnerSpec] is used. Otherwise, the value + /// from the [other] [SpinnerSpec] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [SpinnerSpec] configurations. + @override + SpinnerSpec lerp(SpinnerSpec? other, double t) { + if (other == null) return _$this; + + return SpinnerSpec( + size: MixHelpers.lerpDouble(_$this.size, other.size, t), + strokeWidth: + MixHelpers.lerpDouble(_$this.strokeWidth, other.strokeWidth, t), + color: Color.lerp(_$this.color, other.color, t), + duration: t < 0.5 ? _$this.duration : other.duration, + style: t < 0.5 ? _$this.style : other.style, + animated: t < 0.5 ? _$this.animated : other.animated, + ); + } + + /// The list of properties that constitute the state of this [SpinnerSpec]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [SpinnerSpec] instances for equality. + @override + List get props => [ + _$this.size, + _$this.strokeWidth, + _$this.color, + _$this.duration, + _$this.style, + _$this.animated, + ]; + + SpinnerSpec get _$this => this as SpinnerSpec; +} + +/// Represents the attributes of a [SpinnerSpec]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [SpinnerSpec]. +/// +/// Use this class to configure the attributes of a [SpinnerSpec] and pass it to +/// the [SpinnerSpec] constructor. +final class SpinnerSpecAttribute extends SpecAttribute { + final double? size; + final double? strokeWidth; + final ColorDto? color; + final Duration? duration; + final SpinnerStyle? style; + + const SpinnerSpecAttribute({ + this.size, + this.strokeWidth, + this.color, + this.duration, + this.style, + super.animated, + }); + + /// Resolves to [SpinnerSpec] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final spinnerSpec = SpinnerSpecAttribute(...).resolve(mix); + /// ``` + @override + SpinnerSpec resolve(MixData mix) { + return SpinnerSpec( + size: size, + strokeWidth: strokeWidth, + color: color?.resolve(mix), + duration: duration, + style: style, + animated: animated?.resolve(mix) ?? mix.animation, + ); + } + + /// Merges the properties of this [SpinnerSpecAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [SpinnerSpecAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + SpinnerSpecAttribute merge(SpinnerSpecAttribute? other) { + if (other == null) return this; + + return SpinnerSpecAttribute( + size: other.size ?? size, + strokeWidth: other.strokeWidth ?? strokeWidth, + color: color?.merge(other.color) ?? other.color, + duration: other.duration ?? duration, + style: other.style ?? style, + animated: animated?.merge(other.animated) ?? other.animated, + ); + } + + /// The list of properties that constitute the state of this [SpinnerSpecAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [SpinnerSpecAttribute] instances for equality. + @override + List get props => [ + size, + strokeWidth, + color, + duration, + style, + animated, + ]; +} + +/// Utility class for configuring [SpinnerSpecAttribute] properties. +/// +/// This class provides methods to set individual properties of a [SpinnerSpecAttribute]. +/// Use the methods of this class to configure specific properties of a [SpinnerSpecAttribute]. +base class SpinnerSpecUtility + extends SpecUtility { + /// Utility for defining [SpinnerSpecAttribute.size] + late final size = DoubleUtility((v) => only(size: v)); + + /// Utility for defining [SpinnerSpecAttribute.strokeWidth] + late final strokeWidth = DoubleUtility((v) => only(strokeWidth: v)); + + /// Utility for defining [SpinnerSpecAttribute.color] + late final color = ColorUtility((v) => only(color: v)); + + /// Utility for defining [SpinnerSpecAttribute.duration] + late final duration = DurationUtility((v) => only(duration: v)); + + /// Utility for defining [SpinnerSpecAttribute.style] + late final style = SpinnerStyleUtility((v) => only(style: v)); + + /// Utility for defining [SpinnerSpecAttribute.animated] + late final animated = AnimatedUtility((v) => only(animated: v)); + + SpinnerSpecUtility(super.builder); + + static final self = SpinnerSpecUtility((v) => v); + + /// Returns a new [SpinnerSpecAttribute] with the specified properties. + @override + T only({ + double? size, + double? strokeWidth, + ColorDto? color, + Duration? duration, + SpinnerStyle? style, + AnimatedDataDto? animated, + }) { + return builder(SpinnerSpecAttribute( + size: size, + strokeWidth: strokeWidth, + color: color, + duration: duration, + style: style, + animated: animated, + )); + } +} + +/// A tween that interpolates between two [SpinnerSpec] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [SpinnerSpec] specifications. +class SpinnerSpecTween extends Tween { + SpinnerSpecTween({ + super.begin, + super.end, + }); + + @override + SpinnerSpec lerp(double t) { + if (begin == null && end == null) return const SpinnerSpec(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} diff --git a/packages/remix/lib/components/spinner/spinner_widget.dart b/packages/remix/lib/components/spinner/spinner_widget.dart new file mode 100644 index 000000000..8a40ca44d --- /dev/null +++ b/packages/remix/lib/components/spinner/spinner_widget.dart @@ -0,0 +1,104 @@ +// ignore_for_file: library_private_types_in_public_api + +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/spinner/spinner.style.dart'; +import 'package:remix/components/spinner/spinner.variants.dart'; +import 'package:remix/components/spinner/spinner_painter.dart'; +import 'package:remix/components/spinner/spinner_spec.dart'; + +class RxSpinner extends StatelessWidget { + const RxSpinner({ + this.style, + super.key, + this.size = SpinnerSize.medium, + }); + + final Style? style; + final SpinnerSize size; + + Style _buildStyle() { + return buildSpinnerStyle().merge(style).applyVariant(size).animate(); + } + + @override + Widget build(BuildContext context) { + return SpecBuilder( + style: _buildStyle(), + builder: (context) { + final SpinnerWidget = SpinnerSpec.of(context); + return SpinnerWidget(); + }, + ); + } +} + +class RxSpinnerSpecWidget extends StatefulWidget { + const RxSpinnerSpecWidget({ + this.spec = const SpinnerSpec(), + super.key, + }); + + final SpinnerSpec spec; + + @override + _RxSpinnerSpecWidgetState createState() => _RxSpinnerSpecWidgetState(); +} + +class _RxSpinnerSpecWidgetState extends State + with SingleTickerProviderStateMixin { + late AnimationController controller; + + @override + void initState() { + super.initState(); + controller = AnimationController( + duration: widget.spec.duration, + vsync: this, + )..repeat(); + } + + @override + void didUpdateWidget(covariant RxSpinnerSpecWidget oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.spec.duration != widget.spec.duration) { + controller.duration = widget.spec.duration; + controller.repeat(); + } + } + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final spec = widget.spec; + final color = spec.color; + final strokeWidth = spec.strokeWidth ?? 1; + final size = spec.size; + final painter = spec.style == SpinnerStyle.dotted + ? DottedSpinnerPainter( + animation: controller, + color: color, + strokeWidth: strokeWidth, + ) + : SolidSpinnerPainter( + animation: controller, + color: color, + strokeWidth: strokeWidth, + ); + + return AnimatedBuilder( + animation: controller, + builder: (context, child) { + return CustomPaint( + size: Size(size, size), + painter: painter, + ); + }, + ); + } +} diff --git a/packages/remix/lib/components/switch/switch_spec.dart b/packages/remix/lib/components/switch/switch_spec.dart new file mode 100644 index 000000000..2b4a90d01 --- /dev/null +++ b/packages/remix/lib/components/switch/switch_spec.dart @@ -0,0 +1,22 @@ +import 'package:flutter/widgets.dart'; +import 'package:mix/mix.dart'; +import 'package:mix_annotations/mix_annotations.dart'; + +part 'switch_spec.g.dart'; + +@MixableSpec() +base class SwitchSpec extends Spec with _$SwitchSpec { + final BoxSpec container; + final BoxSpec indicator; + + static const of = _$SwitchSpec.of; + + static const from = _$SwitchSpec.from; + + const SwitchSpec({ + BoxSpec? container, + BoxSpec? indicator, + super.animated, + }) : container = container ?? const BoxSpec(), + indicator = indicator ?? const BoxSpec(); +} diff --git a/packages/remix/lib/components/switch/switch_spec.g.dart b/packages/remix/lib/components/switch/switch_spec.g.dart new file mode 100644 index 000000000..4ec9f523b --- /dev/null +++ b/packages/remix/lib/components/switch/switch_spec.g.dart @@ -0,0 +1,209 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'switch_spec.dart'; + +// ************************************************************************** +// MixableSpecGenerator +// ************************************************************************** + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$SwitchSpec on Spec { + static SwitchSpec from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? + const SwitchSpec(); + } + + /// {@template switch_spec_of} + /// Retrieves the [SwitchSpec] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [SwitchSpec] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [SwitchSpec]. + /// + /// Example: + /// + /// ```dart + /// final switchSpec = SwitchSpec.of(context); + /// ``` + /// {@endtemplate} + static SwitchSpec of(BuildContext context) { + return _$SwitchSpec.from(Mix.of(context)); + } + + /// Creates a copy of this [SwitchSpec] but with the given fields + /// replaced with the new values. + @override + SwitchSpec copyWith({ + BoxSpec? container, + BoxSpec? indicator, + AnimatedData? animated, + }) { + return SwitchSpec( + container: container ?? _$this.container, + indicator: indicator ?? _$this.indicator, + animated: animated ?? _$this.animated, + ); + } + + /// Linearly interpolates between this [SwitchSpec] and another [SwitchSpec] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [SwitchSpec] is returned. When [t] is 1.0, the [other] [SwitchSpec] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [SwitchSpec] is returned. + /// + /// If [other] is null, this method returns the current [SwitchSpec] instance. + /// + /// The interpolation is performed on each property of the [SwitchSpec] using the appropriate + /// interpolation method: + /// + /// - [BoxSpec.lerp] for [container] and [indicator]. + + /// For [animated], the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [SwitchSpec] is used. Otherwise, the value + /// from the [other] [SwitchSpec] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [SwitchSpec] configurations. + @override + SwitchSpec lerp(SwitchSpec? other, double t) { + if (other == null) return _$this; + + return SwitchSpec( + container: _$this.container.lerp(other.container, t), + indicator: _$this.indicator.lerp(other.indicator, t), + animated: t < 0.5 ? _$this.animated : other.animated, + ); + } + + /// The list of properties that constitute the state of this [SwitchSpec]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [SwitchSpec] instances for equality. + @override + List get props => [ + _$this.container, + _$this.indicator, + _$this.animated, + ]; + + SwitchSpec get _$this => this as SwitchSpec; +} + +/// Represents the attributes of a [SwitchSpec]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [SwitchSpec]. +/// +/// Use this class to configure the attributes of a [SwitchSpec] and pass it to +/// the [SwitchSpec] constructor. +final class SwitchSpecAttribute extends SpecAttribute { + final BoxSpecAttribute? container; + final BoxSpecAttribute? indicator; + + const SwitchSpecAttribute({ + this.container, + this.indicator, + super.animated, + }); + + /// Resolves to [SwitchSpec] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final switchSpec = SwitchSpecAttribute(...).resolve(mix); + /// ``` + @override + SwitchSpec resolve(MixData mix) { + return SwitchSpec( + container: container?.resolve(mix), + indicator: indicator?.resolve(mix), + animated: animated?.resolve(mix) ?? mix.animation, + ); + } + + /// Merges the properties of this [SwitchSpecAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [SwitchSpecAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + SwitchSpecAttribute merge(covariant SwitchSpecAttribute? other) { + if (other == null) return this; + + return SwitchSpecAttribute( + container: container?.merge(other.container) ?? other.container, + indicator: indicator?.merge(other.indicator) ?? other.indicator, + animated: animated?.merge(other.animated) ?? other.animated, + ); + } + + /// The list of properties that constitute the state of this [SwitchSpecAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [SwitchSpecAttribute] instances for equality. + @override + List get props => [ + container, + indicator, + animated, + ]; +} + +/// Utility class for configuring [SwitchSpecAttribute] properties. +/// +/// This class provides methods to set individual properties of a [SwitchSpecAttribute]. +/// Use the methods of this class to configure specific properties of a [SwitchSpecAttribute]. +base class SwitchSpecUtility + extends SpecUtility { + /// Utility for defining [SwitchSpecAttribute.container] + late final container = BoxSpecUtility((v) => only(container: v)); + + /// Utility for defining [SwitchSpecAttribute.indicator] + late final indicator = BoxSpecUtility((v) => only(indicator: v)); + + /// Utility for defining [SwitchSpecAttribute.animated] + late final animated = AnimatedUtility((v) => only(animated: v)); + + SwitchSpecUtility(super.builder); + + static final self = SwitchSpecUtility((v) => v); + + /// Returns a new [SwitchSpecAttribute] with the specified properties. + @override + T only({ + BoxSpecAttribute? container, + BoxSpecAttribute? indicator, + AnimatedDataDto? animated, + }) { + return builder(SwitchSpecAttribute( + container: container, + indicator: indicator, + animated: animated, + )); + } +} + +/// A tween that interpolates between two [SwitchSpec] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [SwitchSpec] specifications. +class SwitchSpecTween extends Tween { + SwitchSpecTween({ + super.begin, + super.end, + }); + + @override + SwitchSpec lerp(double t) { + if (begin == null && end == null) return const SwitchSpec(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} diff --git a/packages/remix/lib/components/switch/switch_style.dart b/packages/remix/lib/components/switch/switch_style.dart new file mode 100644 index 000000000..f5c74c3d5 --- /dev/null +++ b/packages/remix/lib/components/switch/switch_style.dart @@ -0,0 +1,123 @@ +import 'package:mix/mix.dart'; +import 'package:remix/components/switch/switch_spec.dart'; +import 'package:remix/components/switch/switch_variants.dart'; +import 'package:remix/helpers/utility_extension.dart'; +import 'package:remix/tokens/remix_tokens.dart'; + +final _util = SwitchSpecUtility.self; + +final _container = _util.container; +final _indicator = _util.indicator; + +Style get _baseStyle => Style( + _container.borderRadius(99), + _indicator.borderRadius(99), + SwitchStatus.on( + _container.alignment.centerRight(), + ), + SwitchStatus.off( + _container.alignment.centerLeft(), + ), + ); + +Style get _solidVariant => Style( + _indicator.color.ref($rx.color.white()), + SwitchStatus.on( + _container.color.ref($rx.color.accent()), + ), + SwitchStatus.off( + _container.color.ref($rx.color.neutral(3)), + ), + $on.disabled( + _container.color.ref($rx.color.neutralAlpha(3)), + _indicator.color.ref($rx.color.neutralAlpha(7)), + ), + ); + +Style get _softVariant => Style( + _indicator.color.ref($rx.color.accentAlpha(11)), + SwitchStatus.on( + _container.color.ref($rx.color.accentAlpha(3)), + ), + SwitchStatus.off( + _container.color.ref($rx.color.neutral(4)), + ), + $on.disabled( + _container.color.ref($rx.color.neutralAlpha(3)), + _indicator.color.ref($rx.color.neutralAlpha(7)), + ), + ); + +Style get _outlineVariant => Style( + _container.color.transparent(), + _container.border.width(1.5), + _container.border.strokeAlign(1), + _indicator.color.ref($rx.color.accentAlpha(11)), + SwitchStatus.on( + _container.border.color.ref($rx.color.accentAlpha(8)), + ), + SwitchStatus.off( + _container.border.color.ref($rx.color.neutral(4)), + ), + $on.disabled( + _container.border.color.ref($rx.color.neutralAlpha(8)), + _indicator.color.ref($rx.color.neutralAlpha(7)), + ), + ); + +Style get _surfaceVariant => Style( + _outlineVariant(), + SwitchStatus.on( + _container.color.ref($rx.color.accentAlpha(3)), + ), + SwitchStatus.off( + _container.color.ref($rx.color.neutralAlpha(3)), + _container.border.color.ref($rx.color.neutral(4)), + ), + $on.disabled( + _container.color.ref($rx.color.neutralAlpha(2)), + ), + ); + +Style get _smallVariant => Style( + _container.width(24), + _container.padding.horizontal(2), + _container.height(16), + _indicator.size(12), + SwitchStatus.off( + _indicator.size(8), + _container.padding.horizontal(2), + ), + ); + +Style get _mediumVariant => Style( + _container.width(32), + _container.padding.horizontal(3), + _container.height(20), + _indicator.size(14), + SwitchStatus.off( + _indicator.size(12), + ), + ); + +Style get _largeVariant => Style( + _container.width(40), + _container.padding.horizontal(3), + _container.height(24), + _indicator.size(18), + SwitchStatus.off(_indicator.size(16)), + ); + +Style buildSwitchStyle() { + return Style( + _baseStyle(), + // Sizes + SwitchSize.small(_smallVariant()), + SwitchSize.medium(_mediumVariant()), + SwitchSize.large(_largeVariant()), + SwitchVariant.solid(_solidVariant()), + SwitchVariant.soft(_softVariant()), + SwitchVariant.outline(_outlineVariant()), + SwitchVariant.surface(_surfaceVariant()), + ); +} diff --git a/packages/remix/lib/components/switch/switch_variants.dart b/packages/remix/lib/components/switch/switch_variants.dart new file mode 100644 index 000000000..cd1f8a4b2 --- /dev/null +++ b/packages/remix/lib/components/switch/switch_variants.dart @@ -0,0 +1,40 @@ +import 'package:remix/helpers/variant.dart'; + +interface class ISwitchVariant extends RemixVariant { + const ISwitchVariant(String name) : super('switch.$name'); +} + +class SwitchStatus extends ISwitchVariant { + const SwitchStatus(String name) : super('status.$name'); + + static const on = SwitchStatus('on'); + static const off = SwitchStatus('off'); + + static List get values => [on, off]; +} + +class SwitchSize extends ISwitchVariant { + const SwitchSize(String name) : super('size.$name'); + + static const small = SwitchSize('small'); + static const medium = SwitchSize('medium'); + static const large = SwitchSize('large'); + + static List get values => [small, medium, large]; +} + +class SwitchVariant extends ISwitchVariant { + const SwitchVariant(String name) : super('variant.$name'); + + static const solid = SwitchVariant('solid'); + static const soft = SwitchVariant('soft'); + static const surface = SwitchVariant('surface'); + static const outline = SwitchVariant('outline'); + + static List get values => [ + solid, + soft, + surface, + outline, + ]; +} diff --git a/packages/remix/lib/components/switch/switch_widget.dart b/packages/remix/lib/components/switch/switch_widget.dart new file mode 100644 index 000000000..2d53e9c17 --- /dev/null +++ b/packages/remix/lib/components/switch/switch_widget.dart @@ -0,0 +1,55 @@ +import 'package:flutter/widgets.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/components/switch/switch_spec.dart'; +import 'package:remix/components/switch/switch_style.dart'; +import 'package:remix/components/switch/switch_variants.dart'; + +class RxSwitch extends StatelessWidget { + const RxSwitch({ + super.key, + required this.value, + required this.onChanged, + this.variant = SwitchVariant.solid, + this.size = SwitchSize.medium, + this.disabled = false, + this.style, + }); + + final bool value; + final ValueChanged onChanged; + final SwitchVariant variant; + final SwitchSize size; + final Style? style; + final bool disabled; + + void _handleOnPress() => onChanged.call(!value); + + Style _buildStyle() { + return buildSwitchStyle().merge(style).applyVariants([ + size, + variant, + value ? SwitchStatus.on : SwitchStatus.off, + ]).animate(); + } + + @override + Widget build(BuildContext context) { + return Pressable( + onPress: disabled ? null : _handleOnPress, + enabled: !disabled, + child: SpecBuilder( + style: _buildStyle(), + builder: (context) { + final spec = SwitchSpec.of(context); + + final ContainerWidget = spec.container; + final IndicatorWidget = spec.indicator; + + return ContainerWidget( + child: IndicatorWidget(), + ); + }, + ), + ); + } +} diff --git a/packages/remix/lib/helpers/color_palette.dart b/packages/remix/lib/helpers/color_palette.dart new file mode 100644 index 000000000..9c74c0947 --- /dev/null +++ b/packages/remix/lib/helpers/color_palette.dart @@ -0,0 +1,2122 @@ +import 'package:flutter/painting.dart'; + +/// Radix color swatch +/// https://www.radix-ui.com/colors/docs/palette-composition/understanding-the-scale +/// + +class RadixColors { + final ColorSwatch swatch; + final ColorSwatch alphaSwatch; + const RadixColors(this.swatch, this.alphaSwatch); + + static const amber = RadixColors(_amber, _amberAlpha); + static const amberDark = RadixColors(_amberDark, _amberDarkAlpha); + static const blackAlpha = RadixColors(_blackAlpha, _blackAlpha); + static const blue = RadixColors(_blue, _blueAlpha); + static const blueDark = RadixColors(_blueDark, _blueDarkAlpha); + static const bronze = RadixColors(_bronze, _bronzeAlpha); + static const bronzeDark = RadixColors(_bronzeDark, _bronzeDarkAlpha); + static const brown = RadixColors(_brown, _brownAlpha); + static const brownDark = RadixColors(_brownDark, _brownDarkAlpha); + static const crimson = RadixColors(_crimson, _crimsonAlpha); + static const crimsonDark = RadixColors(_crimsonDark, _crimsonDarkAlpha); + static const cyan = RadixColors(_cyan, _cyanAlpha); + static const cyanDark = RadixColors(_cyanDark, _cyanDarkAlpha); + static const gold = RadixColors(_gold, _goldAlpha); + static const goldDark = RadixColors(_goldDark, _goldDarkAlpha); + static const grass = RadixColors(_grass, _grassAlpha); + static const grassDark = RadixColors(_grassDark, _grassDarkAlpha); + static const gray = RadixColors(_gray, _grayAlpha); + static const grayDark = RadixColors(_grayDark, _grayDarkAlpha); + static const green = RadixColors(_green, _greenAlpha); + static const greenDark = RadixColors(_greenDark, _greenDarkAlpha); + static const indigo = RadixColors(_indigo, _indigoAlpha); + static const indigoDark = RadixColors(_indigoDark, _indigoDarkAlpha); + static const lime = RadixColors(_lime, _limeAlpha); + static const limeDark = RadixColors(_limeDark, _limeDarkAlpha); + static const mauve = RadixColors(_mauve, _mauveAlpha); + static const mauveDark = RadixColors(_mauveDark, _mauveDarkAlpha); + static const mint = RadixColors(_mint, _mintAlpha); + static const mintDark = RadixColors(_mintDark, _mintDarkAlpha); + static const orange = RadixColors(_orange, _orangeAlpha); + static const orangeDark = RadixColors(_orangeDark, _orangeDarkAlpha); + static const pink = RadixColors(_pink, _pinkAlpha); + static const pinkDark = RadixColors(_pinkDark, _pinkDarkAlpha); + static const plum = RadixColors(_plum, _plumAlpha); + static const plumDark = RadixColors(_plumDark, _plumDarkAlpha); + static const purple = RadixColors(_purple, _purpleAlpha); + static const purpleDark = RadixColors(_purpleDark, _purpleDarkAlpha); + static const red = RadixColors(_red, _redAlpha); + static const redDark = RadixColors(_redDark, _redDarkAlpha); + static const sand = RadixColors(_sand, _sandAlpha); + static const sandDark = RadixColors(_sandDark, _sandDarkAlpha); + static const sky = RadixColors(_sky, _skyAlpha); + static const skyDark = RadixColors(_skyDark, _skyDarkAlpha); + static const slate = RadixColors(_slate, _slateAlpha); + static const slateDark = RadixColors(_slateDark, _slateDarkAlpha); + static const teal = RadixColors(_teal, _tealAlpha); + static const tealDark = RadixColors(_tealDark, _tealDarkAlpha); + static const tomato = RadixColors(_tomato, _tomatoAlpha); + static const tomatoDark = RadixColors(_tomatoDark, _tomatoDarkAlpha); + static const violet = RadixColors(_violet, _violetAlpha); + static const violetDark = RadixColors(_violetDark, _violetDarkAlpha); + static const yellow = RadixColors(_yellow, _yellowAlpha); + static const yellowDark = RadixColors(_yellowDark, _yellowDarkAlpha); + static const olive = RadixColors(_olive, _oliveAlpha); + static const oliveDark = RadixColors(_oliveDark, _oliveDarkAlpha); + static const whiteAlpha = RadixColors(_whiteAlpha, _whiteAlpha); + static const sage = RadixColors(_sage, _sageAlpha); + static const sageDark = RadixColors(_sageDark, _sageDarkAlpha); +} + +const _amber = ColorSwatch( + 0xffee9d2b, + { + 1: Color(0xfffefdfb), + 2: Color(0xfffff9ed), + 3: Color(0xfffff4d5), + 4: Color(0xffffecbc), + 5: Color(0xffffe3a2), + 6: Color(0xffffd386), + 7: Color(0xfff3ba63), + 8: Color(0xffee9d2b), + 9: Color(0xffffb224), + 10: Color(0xffffa01c), + 11: Color(0xffad5700), + 12: Color(0xff4e2009) + }, +); + +const _amberAlpha = ColorSwatch( + 0xd4ea8900, + { + 1: Color(0x04c08205), + 2: Color(0x12ffab02), + 3: Color(0x2affbb01), + 4: Color(0x43ffb700), + 5: Color(0x5dffb300), + 6: Color(0x79ffa201), + 7: Color(0x9cec8d00), + 8: Color(0xd4ea8900), + 9: Color(0xdbffa600), + 10: Color(0xe3ff9500), + 11: Color(0xfaab5300), + 12: Color(0xf6481800) + }, +); + +const _amberDark = ColorSwatch( + 0xffffb224, + { + 1: Color(0xff1f1300), + 2: Color(0xff271700), + 3: Color(0xff341c00), + 4: Color(0xff3f2200), + 5: Color(0xff4a2900), + 6: Color(0xff573300), + 7: Color(0xff693f05), + 8: Color(0xff824e00), + 9: Color(0xffffb224), + 10: Color(0xffffcb47), + 11: Color(0xfff1a10d), + 12: Color(0xfffef3dd) + }, +); + +const _amberDarkAlpha = ColorSwatch( + 0xfaffb625, + { + 1: Color(0x00000000), + 2: Color(0x09fd8300), + 3: Color(0x18fe7300), + 4: Color(0x24ff7b00), + 5: Color(0x31ff8400), + 6: Color(0x40ff9500), + 7: Color(0x54ff970f), + 8: Color(0x71ff9900), + 9: Color(0xfaffb625), + 10: Color(0xfaffce48), + 11: Color(0xefffab0e), + 12: Color(0xfafff8e1) + }, +); + +const _blackAlpha = ColorSwatch( + 0xe8000000, + { + 1: Color(0x03000000), + 2: Color(0x07000000), + 3: Color(0x0c000000), + 4: Color(0x12000000), + 5: Color(0x17000000), + 6: Color(0x1d000000), + 7: Color(0x24000000), + 8: Color(0x38000000), + 9: Color(0x70000000), + 10: Color(0x7a000000), + 11: Color(0x90000000), + 12: Color(0xe8000000) + }, +); + +const _blue = ColorSwatch( + 0xff0091ff, + { + 1: Color(0xfffbfdff), + 2: Color(0xfff5faff), + 3: Color(0xffedf6ff), + 4: Color(0xffe1f0ff), + 5: Color(0xffcee7fe), + 6: Color(0xffb7d9f8), + 7: Color(0xff96c7f2), + 8: Color(0xff5eb0ef), + 9: Color(0xff0091ff), + 10: Color(0xff0081f1), + 11: Color(0xff006adc), + 12: Color(0xff00254d) + }, +); + +const _blueAlpha = ColorSwatch( + 0xfa0091ff, + { + 1: Color(0x040582ff), + 2: Color(0x0a0582ff), + 3: Color(0x120280ff), + 4: Color(0x1e0180ff), + 5: Color(0x300180ef), + 6: Color(0x480177e6), + 7: Color(0x690077df), + 8: Color(0xa10082e6), + 9: Color(0xfa0091ff), + 10: Color(0xfa0080f1), + 11: Color(0xfa0066db), + 12: Color(0xfa002149) + }, +); + +const _blueDark = ColorSwatch( + 0xff0091ff, + { + 1: Color(0xff0f1720), + 2: Color(0xff0f1b2d), + 3: Color(0xff10243e), + 4: Color(0xff102a4c), + 5: Color(0xff0f3058), + 6: Color(0xff0d3868), + 7: Color(0xff0a4481), + 8: Color(0xff0954a5), + 9: Color(0xff0091ff), + 10: Color(0xff369eff), + 11: Color(0xff52a9ff), + 12: Color(0xffeaf6ff) + }, +); + +const _blueDarkAlpha = ColorSwatch( + 0xfa0095ff, + { + 1: Color(0x00000000), + 2: Color(0x0f0f5afc), + 3: Color(0x221677fe), + 4: Color(0x321476fe), + 5: Color(0x400f7bfe), + 6: Color(0x52097cff), + 7: Color(0x6f047dff), + 8: Color(0x98057eff), + 9: Color(0xfa0095ff), + 10: Color(0xfa37a1ff), + 11: Color(0xfa53acff), + 12: Color(0xfaeffbff) + }, +); + +const _bronze = ColorSwatch( + 0xffa18072, + { + 1: Color(0xfffdfcfc), + 2: Color(0xfffdf8f6), + 3: Color(0xfff8f1ee), + 4: Color(0xfff2e8e4), + 5: Color(0xffeaddd7), + 6: Color(0xffe0cec7), + 7: Color(0xffd1b9b0), + 8: Color(0xffbfa094), + 9: Color(0xffa18072), + 10: Color(0xff977669), + 11: Color(0xff846358), + 12: Color(0xff43302b) + }, +); + +const _bronzeAlpha = ColorSwatch( + 0x8d551a00, + { + 1: Color(0x03580505), + 2: Color(0x09c73c05), + 3: Color(0x11972e01), + 4: Color(0x1b842600), + 5: Color(0x28792700), + 6: Color(0x38722100), + 7: Color(0x4f6e2100), + 8: Color(0x6b671d00), + 9: Color(0x8d551a00), + 10: Color(0x964e1600), + 11: Color(0xa7431100), + 12: Color(0xd41d0600) + }, +); + +const _bronzeDark = ColorSwatch( + 0xffa18072, + { + 1: Color(0xff191514), + 2: Color(0xff1f1917), + 3: Color(0xff2a211f), + 4: Color(0xff332824), + 5: Color(0xff3b2e29), + 6: Color(0xff453530), + 7: Color(0xff57433c), + 8: Color(0xff74594e), + 9: Color(0xffa18072), + 10: Color(0xffb08c7d), + 11: Color(0xffcba393), + 12: Color(0xfff9ede7) + }, +); + +const _bronzeDarkAlpha = ColorSwatch( + 0x97ffcab3, + { + 1: Color(0x00000000), + 2: Color(0x07f7aa83), + 3: Color(0x13ffb7a9), + 4: Color(0x1dfdbca0), + 5: Color(0x26ffbea2), + 6: Color(0x31febca6), + 7: Color(0x45ffbfa8), + 8: Color(0x65ffc1a6), + 9: Color(0x97ffcab3), + 10: Color(0xa8ffcab4), + 11: Color(0xc5ffccb8), + 12: Color(0xf8fff3ed) + }, +); + +const _brown = ColorSwatch( + 0xffad7f58, + { + 1: Color(0xfffefdfc), + 2: Color(0xfffcf9f6), + 3: Color(0xfff8f1ea), + 4: Color(0xfff4e9dd), + 5: Color(0xffefddcc), + 6: Color(0xffe8cdb5), + 7: Color(0xffddb896), + 8: Color(0xffd09e72), + 9: Color(0xffad7f58), + 10: Color(0xffa07653), + 11: Color(0xff886349), + 12: Color(0xff3f2c22) + }, +); + +const _brownAlpha = ColorSwatch( + 0xa7823d00, + { + 1: Color(0x03ab5805), + 2: Color(0x09ab5805), + 3: Color(0x15ab5602), + 4: Color(0x22ad5a01), + 5: Color(0x33af5500), + 6: Color(0x4ab05201), + 7: Color(0x69ac5300), + 8: Color(0x8daa4f00), + 9: Color(0xa7823d00), + 10: Color(0xac723300), + 11: Color(0xb6582500), + 12: Color(0xdd220c00) + }, +); + +const _brownDark = ColorSwatch( + 0xffad7f58, + { + 1: Color(0xff191513), + 2: Color(0xff221813), + 3: Color(0xff2e201a), + 4: Color(0xff36261e), + 5: Color(0xff3e2c22), + 6: Color(0xff493528), + 7: Color(0xff5c4332), + 8: Color(0xff775940), + 9: Color(0xffad7f58), + 10: Color(0xffbd8b60), + 11: Color(0xffdba16e), + 12: Color(0xfffaf0e5) + }, +); + +const _brownDarkAlpha = ColorSwatch( + 0xa4ffba7e, + { + 1: Color(0x00000000), + 2: Color(0x09ff6913), + 3: Color(0x16fd9163), + 4: Color(0x1ffe9f6c), + 5: Color(0x28feac72), + 6: Color(0x35feb079), + 7: Color(0x4afeb47e), + 8: Color(0x68febc82), + 9: Color(0xa4ffba7e), + 10: Color(0xb6ffbb7f), + 11: Color(0xd7ffbb7f), + 12: Color(0xfafff5e9) + }, +); + +const _crimson = ColorSwatch( + 0xffe93d82, + { + 1: Color(0xfffffcfd), + 2: Color(0xfffff7fb), + 3: Color(0xfffeeff6), + 4: Color(0xfffce5f0), + 5: Color(0xfff9d8e7), + 6: Color(0xfff4c6db), + 7: Color(0xffedadc8), + 8: Color(0xffe58fb1), + 9: Color(0xffe93d82), + 10: Color(0xffe03177), + 11: Color(0xffd31e66), + 12: Color(0xff3d0d1d) + }, +); + +const _crimsonAlpha = ColorSwatch( + 0xc2e2005a, + { + 1: Color(0x03ff0558), + 2: Color(0x08ff0582), + 3: Color(0x10ef0170), + 4: Color(0x1ae2006d), + 5: Color(0x27d80061), + 6: Color(0x39ce015d), + 7: Color(0x52c70053), + 8: Color(0x70c4004f), + 9: Color(0xc2e2005a), + 10: Color(0xced90057), + 11: Color(0xe1cd0052), + 12: Color(0xf2330011) + }, +); + +const _crimsonDark = ColorSwatch( + 0xffe93d82, + { + 1: Color(0xff1d1418), + 2: Color(0xff27141c), + 3: Color(0xff3c1827), + 4: Color(0xff481a2d), + 5: Color(0xff541b33), + 6: Color(0xff641d3b), + 7: Color(0xff801d45), + 8: Color(0xffae1955), + 9: Color(0xffe93d82), + 10: Color(0xfff04f88), + 11: Color(0xfff76190), + 12: Color(0xfffeecf4) + }, +); + +const _crimsonDarkAlpha = ColorSwatch( + 0xe6ff418d, + { + 1: Color(0x00000000), + 2: Color(0x0bfb1471), + 3: Color(0x23fe3186), + 4: Color(0x31fe3384), + 5: Color(0x3efe3186), + 6: Color(0x50fe3186), + 7: Color(0x70fe287e), + 8: Color(0xa4ff1c77), + 9: Color(0xe6ff418d), + 10: Color(0xeeff538f), + 11: Color(0xf6ff6495), + 12: Color(0xfafff0f8) + }, +); + +const _cyan = ColorSwatch( + 0xff05a2c2, + { + 1: Color(0xfffafdfe), + 2: Color(0xfff2fcfd), + 3: Color(0xffe7f9fb), + 4: Color(0xffd8f3f6), + 5: Color(0xffc4eaef), + 6: Color(0xffaadee6), + 7: Color(0xff84cdda), + 8: Color(0xff3db9cf), + 9: Color(0xff05a2c2), + 10: Color(0xff0894b3), + 11: Color(0xff0c7792), + 12: Color(0xff04313c) + }, +); + +const _cyanAlpha = ColorSwatch( + 0xfa00a1c1, + { + 1: Color(0x05059bcd), + 2: Color(0x0d00c6d8), + 3: Color(0x1802c0d5), + 4: Color(0x2700b1c4), + 5: Color(0x3b01a4ba), + 6: Color(0x55019cb4), + 7: Color(0x7b0097b2), + 8: Color(0xc200a3c0), + 9: Color(0xfa00a1c1), + 10: Color(0xf70090b0), + 11: Color(0xf300718d), + 12: Color(0xfa002d38) + }, +); + +const _cyanDark = ColorSwatch( + 0xff05a2c2, + { + 1: Color(0xff07191d), + 2: Color(0xff061e24), + 3: Color(0xff072830), + 4: Color(0xff07303b), + 5: Color(0xff073844), + 6: Color(0xff064150), + 7: Color(0xff045063), + 8: Color(0xff00647d), + 9: Color(0xff05a2c2), + 10: Color(0xff00b1cc), + 11: Color(0xff00c2d7), + 12: Color(0xffe1f8fa) + }, +); + +const _cyanDarkAlpha = ColorSwatch( + 0xba04d5ff, + { + 1: Color(0x00000000), + 2: Color(0x0800bbff), + 3: Color(0x1607cbfc), + 4: Color(0x2207c5ff), + 5: Color(0x2c07cdfe), + 6: Color(0x3a02c8ff), + 7: Color(0x4f00ccff), + 8: Color(0x6c00c8ff), + 9: Color(0xba04d5ff), + 10: Color(0xc600ddff), + 11: Color(0xd200e5fe), + 12: Color(0xf9e6fdff) + }, +); + +const _gold = ColorSwatch( + 0xff978365, + { + 1: Color(0xfffdfdfc), + 2: Color(0xfffbf9f2), + 3: Color(0xfff5f2e9), + 4: Color(0xffeeeadd), + 5: Color(0xffe5dfd0), + 6: Color(0xffdad1bd), + 7: Color(0xffcbbda4), + 8: Color(0xffb8a383), + 9: Color(0xff978365), + 10: Color(0xff8c795d), + 11: Color(0xff776750), + 12: Color(0xff3b352b) + }, +); + +const _goldAlpha = ColorSwatch( + 0x9a533200, + { + 1: Color(0x03585805), + 2: Color(0x0db08a00), + 3: Color(0x168c6a02), + 4: Color(0x22806301), + 5: Color(0x2f725201), + 6: Color(0x42704d00), + 7: Color(0x5b6e4500), + 8: Color(0x7c6d4200), + 9: Color(0x9a533200), + 10: Color(0xa24a2d00), + 11: Color(0xaf392100), + 12: Color(0xd4130c00) + }, +); + +const _goldDark = ColorSwatch( + 0xff978365, + { + 1: Color(0xff171613), + 2: Color(0xff1c1a15), + 3: Color(0xff26231c), + 4: Color(0xff2e2a21), + 5: Color(0xff353026), + 6: Color(0xff3e382c), + 7: Color(0xff504737), + 8: Color(0xff6b5d48), + 9: Color(0xff978365), + 10: Color(0xffa59071), + 11: Color(0xffbfa888), + 12: Color(0xfff7f4e7) + }, +); + +const _goldDarkAlpha = ColorSwatch( + 0x8dffdca7, + { + 1: Color(0x00000000), + 2: Color(0x06facb6e), + 3: Color(0x11fede9d), + 4: Color(0x1afdde9f), + 5: Color(0x21fedda5), + 6: Color(0x2bfedfa7), + 7: Color(0x3fffdda6), + 8: Color(0x5dfed9a5), + 9: Color(0x8dffdca7), + 10: Color(0x9cffdcac), + 11: Color(0xb9ffe0b4), + 12: Color(0xf6fffcee) + }, +); + +const _grass = ColorSwatch( + 0xff46a758, + { + 1: Color(0xfffbfefb), + 2: Color(0xfff3fcf3), + 3: Color(0xffebf9eb), + 4: Color(0xffdff3df), + 5: Color(0xffceebcf), + 6: Color(0xffb7dfba), + 7: Color(0xff97cf9c), + 8: Color(0xff65ba75), + 9: Color(0xff46a758), + 10: Color(0xff3d9a50), + 11: Color(0xff297c3b), + 12: Color(0xff1b311e) + }, +); + +const _grassAlpha = ColorSwatch( + 0xb9008619, + { + 1: Color(0x0405c005), + 2: Color(0x0c05c005), + 3: Color(0x1402b302), + 4: Color(0x2001a001), + 5: Color(0x31019706), + 6: Color(0x48018e0c), + 7: Color(0x68008a0c), + 8: Color(0x9a008d1a), + 9: Color(0xb9008619), + 10: Color(0xc2007a19), + 11: Color(0xd6006316), + 12: Color(0xe4001904) + }, +); + +const _grassDark = ColorSwatch( + 0xff46a758, + { + 1: Color(0xff0d1912), + 2: Color(0xff0f1e13), + 3: Color(0xff132819), + 4: Color(0xff16301d), + 5: Color(0xff193921), + 6: Color(0xff1d4427), + 7: Color(0xff245530), + 8: Color(0xff2f6e3b), + 9: Color(0xff46a758), + 10: Color(0xff55b467), + 11: Color(0xff63c174), + 12: Color(0xffe5fbeb) + }, +); + +const _grassDarkAlpha = ColorSwatch( + 0x9e69ff82, + { + 1: Color(0x00000000), + 2: Color(0x0668fc3f), + 3: Color(0x1168fc7b), + 4: Color(0x1a67ff80), + 5: Color(0x2463fe7d), + 6: Color(0x3063ff82), + 7: Color(0x4365ff84), + 8: Color(0x5e69ff82), + 9: Color(0x9e69ff82), + 10: Color(0xac78ff91), + 11: Color(0xba83ff97), + 12: Color(0xfaeafff0) + }, +); + +const _gray = ColorSwatch( + 0xff8f8f8f, + { + 1: Color(0xfffcfcfc), + 2: Color(0xfff8f8f8), + 3: Color(0xfff3f3f3), + 4: Color(0xffededed), + 5: Color(0xffe8e8e8), + 6: Color(0xffe2e2e2), + 7: Color(0xffdbdbdb), + 8: Color(0xffc7c7c7), + 9: Color(0xff8f8f8f), + 10: Color(0xff858585), + 11: Color(0xff6f6f6f), + 12: Color(0xff171717) + }, +); + +const _grayAlpha = ColorSwatch( + 0x70000000, + { + 1: Color(0x03000000), + 2: Color(0x07000000), + 3: Color(0x0c000000), + 4: Color(0x12000000), + 5: Color(0x17000000), + 6: Color(0x1d000000), + 7: Color(0x24000000), + 8: Color(0x38000000), + 9: Color(0x70000000), + 10: Color(0x7a000000), + 11: Color(0x90000000), + 12: Color(0xe8000000) + }, +); + +const _grayDark = ColorSwatch( + 0xff707070, + { + 1: Color(0xff161616), + 2: Color(0xff1c1c1c), + 3: Color(0xff232323), + 4: Color(0xff282828), + 5: Color(0xff2e2e2e), + 6: Color(0xff343434), + 7: Color(0xff3e3e3e), + 8: Color(0xff505050), + 9: Color(0xff707070), + 10: Color(0xff7e7e7e), + 11: Color(0xffa0a0a0), + 12: Color(0xffededed) + }, +); + +const _grayDarkAlpha = ColorSwatch( + 0x62ffffff, + { + 1: Color(0x00ffffff), + 2: Color(0x07ffffff), + 3: Color(0x0effffff), + 4: Color(0x14ffffff), + 5: Color(0x1affffff), + 6: Color(0x21ffffff), + 7: Color(0x2cffffff), + 8: Color(0x3fffffff), + 9: Color(0x62ffffff), + 10: Color(0x72ffffff), + 11: Color(0x97ffffff), + 12: Color(0xebffffff) + }, +); + +const _green = ColorSwatch( + 0xff30a46c, + { + 1: Color(0xfffbfefc), + 2: Color(0xfff2fcf5), + 3: Color(0xffe9f9ee), + 4: Color(0xffddf3e4), + 5: Color(0xffccebd7), + 6: Color(0xffb4dfc4), + 7: Color(0xff92ceac), + 8: Color(0xff5bb98c), + 9: Color(0xff30a46c), + 10: Color(0xff299764), + 11: Color(0xff18794e), + 12: Color(0xff153226) + }, +); + +const _greenAlpha = ColorSwatch( + 0xcf008f4a, + { + 1: Color(0x0405c043), + 2: Color(0x0d00c43b), + 3: Color(0x1602ba3c), + 4: Color(0x2201a635), + 5: Color(0x33009b36), + 6: Color(0x4b019336), + 7: Color(0x6d008c3d), + 8: Color(0xa400934c), + 9: Color(0xcf008f4a), + 10: Color(0xd6008346), + 11: Color(0xe7006b3b), + 12: Color(0xea002012) + }, +); + +const _greenDark = ColorSwatch( + 0xff30a46c, + { + 1: Color(0xff0d1912), + 2: Color(0xff0c1f17), + 3: Color(0xff0f291e), + 4: Color(0xff113123), + 5: Color(0xff133929), + 6: Color(0xff164430), + 7: Color(0xff1b543a), + 8: Color(0xff236e4a), + 9: Color(0xff30a46c), + 10: Color(0xff3cb179), + 11: Color(0xff4cc38a), + 12: Color(0xffe5fbeb) + }, +); + +const _greenDarkAlpha = ColorSwatch( + 0x9a47ffa6, + { + 1: Color(0x00000000), + 2: Color(0x0700f7ca), + 3: Color(0x122afebe), + 4: Color(0x1b33feb3), + 5: Color(0x2438feb5), + 6: Color(0x303dffb1), + 7: Color(0x4243ffad), + 8: Color(0x5e49ffaa), + 9: Color(0x9a47ffa6), + 10: Color(0xa954ffaf), + 11: Color(0xbd62ffb3), + 12: Color(0xfaeafff0) + }, +); + +const _indigo = ColorSwatch( + 0xff3e63dd, + { + 1: Color(0xfffdfdfe), + 2: Color(0xfff8faff), + 3: Color(0xfff0f4ff), + 4: Color(0xffe6edfe), + 5: Color(0xffd9e2fc), + 6: Color(0xffc6d4f9), + 7: Color(0xffaec0f5), + 8: Color(0xff8da4ef), + 9: Color(0xff3e63dd), + 10: Color(0xff3a5ccc), + 11: Color(0xff3451b2), + 12: Color(0xff101d46) + }, +); + +const _indigoAlpha = ColorSwatch( + 0xc10031d2, + { + 1: Color(0x02050582), + 2: Color(0x07054cff), + 3: Color(0x0f0144ff), + 4: Color(0x190247f5), + 5: Color(0x26023ceb), + 6: Color(0x39013de4), + 7: Color(0x510038e0), + 8: Color(0x720134db), + 9: Color(0xc10031d2), + 10: Color(0xc5002cbd), + 11: Color(0xcb00259e), + 12: Color(0xef000e3a) + }, +); + +const _indigoDark = ColorSwatch( + 0xff3e63dd, + { + 1: Color(0xff131620), + 2: Color(0xff15192d), + 3: Color(0xff192140), + 4: Color(0xff1c274f), + 5: Color(0xff1f2c5c), + 6: Color(0xff22346e), + 7: Color(0xff273e89), + 8: Color(0xff2f4eb2), + 9: Color(0xff3e63dd), + 10: Color(0xff5373e7), + 11: Color(0xff849dff), + 12: Color(0xffeef1fd) + }, +); + +const _indigoDarkAlpha = ColorSwatch( + 0xd84571ff, + { + 1: Color(0x00000000), + 2: Color(0x0f3549fc), + 3: Color(0x253c63fe), + 4: Color(0x363d67ff), + 5: Color(0x453f69fe), + 6: Color(0x593e6bff), + 7: Color(0x783d6aff), + 8: Color(0xa73e6bff), + 9: Color(0xd84571ff), + 10: Color(0xe45a7eff), + 11: Color(0xfa86a0ff), + 12: Color(0xfaf2f5ff) + }, +); + +const _lime = ColorSwatch( + 0xff94ba2c, + { + 1: Color(0xfffcfdfa), + 2: Color(0xfff7fcf0), + 3: Color(0xffeefadc), + 4: Color(0xffe4f7c7), + 5: Color(0xffd7f2b0), + 6: Color(0xffc9e894), + 7: Color(0xffb1d16a), + 8: Color(0xff94ba2c), + 9: Color(0xff99d52a), + 10: Color(0xff93c926), + 11: Color(0xff5d770d), + 12: Color(0xff263209) + }, +); + +const _limeAlpha = ColorSwatch( + 0xd37eac00, + { + 1: Color(0x05699b05), + 2: Color(0x0f77cc01), + 3: Color(0x2384db01), + 4: Color(0x3883db00), + 5: Color(0x4f7cd500), + 6: Color(0x6b7fc800), + 7: Color(0x9578b000), + 8: Color(0xd37eac00), + 9: Color(0xd585cd00), + 10: Color(0xd980c000), + 11: Color(0xf2547000), + 12: Color(0xf61e2b00) + }, +); + +const _limeDark = ColorSwatch( + 0xff99d52a, + { + 1: Color(0xff141807), + 2: Color(0xff181d08), + 3: Color(0xff1e260d), + 4: Color(0xff252e0f), + 5: Color(0xff2b3711), + 6: Color(0xff344213), + 7: Color(0xff415215), + 8: Color(0xff536716), + 9: Color(0xff99d52a), + 10: Color(0xffc4f042), + 11: Color(0xff87be22), + 12: Color(0xffeffbdd) + }, +); + +const _limeDarkAlpha = ColorSwatch( + 0xd1b7ff32, + { + 1: Color(0x00000000), + 2: Color(0x06cafb35), + 3: Color(0x10b8fd6a), + 4: Color(0x18c4fd5b), + 5: Color(0x22befe51), + 6: Color(0x2ec5ff49), + 7: Color(0x40c8fe3f), + 8: Color(0x57ccff33), + 9: Color(0xd1b7ff32), + 10: Color(0xefd1ff46), + 11: Color(0xb7b5ff2c), + 12: Color(0xfaf4ffe1) + }, +); + +const _mauve = ColorSwatch( + 0xff908e96, + { + 1: Color(0xfffdfcfd), + 2: Color(0xfff9f8f9), + 3: Color(0xfff4f2f4), + 4: Color(0xffeeedef), + 5: Color(0xffe9e8ea), + 6: Color(0xffe4e2e4), + 7: Color(0xffdcdbdd), + 8: Color(0xffc8c7cb), + 9: Color(0xff908e96), + 10: Color(0xff86848d), + 11: Color(0xff6f6e77), + 12: Color(0xff1a1523) + }, +); + +const _mauveAlpha = ColorSwatch( + 0x71050012, + { + 1: Color(0x03580558), + 2: Color(0x07290529), + 3: Color(0x0d270027), + 4: Color(0x1210011e), + 5: Color(0x170d0218), + 6: Color(0x1d120112), + 7: Color(0x2408010f), + 8: Color(0x38050012), + 9: Color(0x71050012), + 10: Color(0x7b040013), + 11: Color(0x91020010), + 12: Color(0xea05000f) + }, +); + +const _mauveDark = ColorSwatch( + 0xff706f78, + { + 1: Color(0xff161618), + 2: Color(0xff1c1c1f), + 3: Color(0xff232326), + 4: Color(0xff28282c), + 5: Color(0xff2e2e32), + 6: Color(0xff34343a), + 7: Color(0xff3e3e44), + 8: Color(0xff504f57), + 9: Color(0xff706f78), + 10: Color(0xff7e7d86), + 11: Color(0xffa09fa6), + 12: Color(0xffededef) + }, +); + +const _mauveDarkAlpha = ColorSwatch( + 0x6aeeecff, + { + 1: Color(0x00000000), + 2: Color(0x08d7d7fa), + 3: Color(0x10ebebfe), + 4: Color(0x16e5e5fe), + 5: Color(0x1deaeafe), + 6: Color(0x26e1e1fe), + 7: Color(0x31e8e8fe), + 8: Color(0x46eae7ff), + 9: Color(0x6aeeecff), + 10: Color(0x7af0eeff), + 11: Color(0x9df7f5ff), + 12: Color(0xedfdfdff) + }, +); + +const _mint = ColorSwatch( + 0xff40c4aa, + { + 1: Color(0xfff9fefd), + 2: Color(0xffeffefa), + 3: Color(0xffe1fbf4), + 4: Color(0xffd2f7ed), + 5: Color(0xffc0efe3), + 6: Color(0xffa5e4d4), + 7: Color(0xff7dd4c0), + 8: Color(0xff40c4aa), + 9: Color(0xff70e1c8), + 10: Color(0xff69d9c1), + 11: Color(0xff147d6f), + 12: Color(0xff09342e) + }, +); + +const _mintAlpha = ColorSwatch( + 0xbf00b08d, + { + 1: Color(0x0605d5ac), + 2: Color(0x1001efb0), + 3: Color(0x1e01dda2), + 4: Color(0x2d01d29a), + 5: Color(0x3f01be8f), + 6: Color(0x5a00b386), + 7: Color(0x8200ab83), + 8: Color(0xbf00b08d), + 9: Color(0x8f00c99e), + 10: Color(0x9600be95), + 11: Color(0xeb007263), + 12: Color(0xf6002d27) + }, +); + +const _mintDark = ColorSwatch( + 0xff70e1c8, + { + 1: Color(0xff081917), + 2: Color(0xff05201e), + 3: Color(0xff052926), + 4: Color(0xff04312c), + 5: Color(0xff033a34), + 6: Color(0xff01453d), + 7: Color(0xff00564a), + 8: Color(0xff006d5b), + 9: Color(0xff70e1c8), + 10: Color(0xff95f3d9), + 11: Color(0xff25d0ab), + 12: Color(0xffe7fcf7) + }, +); + +const _mintDarkAlpha = ColorSwatch( + 0xde80ffe3, + { + 1: Color(0x00000000), + 2: Color(0x0800fbfb), + 3: Color(0x1200fded), + 4: Color(0x1b00fde0), + 5: Color(0x2500fee0), + 6: Color(0x3100fedc), + 7: Color(0x4400fed8), + 8: Color(0x5d00fed0), + 9: Color(0xde80ffe3), + 10: Color(0xf29dffe3), + 11: Color(0xcb2cffd1), + 12: Color(0xfaecfffb) + }, +); + +const _olive = ColorSwatch( + 0xff8b918a, + { + 1: Color(0xfffcfdfc), + 2: Color(0xfff8faf8), + 3: Color(0xfff2f4f2), + 4: Color(0xffecefec), + 5: Color(0xffe6e9e6), + 6: Color(0xffe0e4e0), + 7: Color(0xffd8dcd8), + 8: Color(0xffc3c8c2), + 9: Color(0xff8b918a), + 10: Color(0xff818780), + 11: Color(0xff6b716a), + 12: Color(0xff141e12) + }, +); + +const _oliveAlpha = ColorSwatch( + 0x75020f00, + { + 1: Color(0x03055805), + 2: Color(0x07054d05), + 3: Color(0x0d002700), + 4: Color(0x13022a02), + 5: Color(0x19022102), + 6: Color(0x1f012201), + 7: Color(0x27001a00), + 8: Color(0x3d051a01), + 9: Color(0x75020f00), + 10: Color(0x7f030e00), + 11: Color(0x95020c00), + 12: Color(0xed020d00) + }, +); + +const _oliveDark = ColorSwatch( + 0xff687366, + { + 1: Color(0xff151715), + 2: Color(0xff1a1d19), + 3: Color(0xff20241f), + 4: Color(0xff262925), + 5: Color(0xff2b2f2a), + 6: Color(0xff313530), + 7: Color(0xff3b3f3a), + 8: Color(0xff4c514b), + 9: Color(0xff687366), + 10: Color(0xff778175), + 11: Color(0xff9aa299), + 12: Color(0xffeceeec) + }, +); + +const _oliveDarkAlpha = ColorSwatch( + 0x65e6ffe1, + { + 1: Color(0x00000000), + 2: Color(0x07d5feaf), + 3: Color(0x0fd6fbc4), + 4: Color(0x14effee2), + 5: Color(0x1be9fedf), + 6: Color(0x21ecfee5), + 7: Color(0x2cf1feeb), + 8: Color(0x40f1ffed), + 9: Color(0x65e6ffe1), + 10: Color(0x75ebffe7), + 11: Color(0x99f3fff1), + 12: Color(0xecfdfffd) + }, +); + +const _orange = ColorSwatch( + 0xfff76808, + { + 1: Color(0xfffefcfb), + 2: Color(0xfffef8f4), + 3: Color(0xfffff1e7), + 4: Color(0xffffe8d7), + 5: Color(0xffffdcc3), + 6: Color(0xffffcca7), + 7: Color(0xffffb381), + 8: Color(0xfffa934e), + 9: Color(0xfff76808), + 10: Color(0xffed5f00), + 11: Color(0xffbd4b00), + 12: Color(0xff451e11) + }, +); + +const _orangeAlpha = ColorSwatch( + 0xf7f76300, + { + 1: Color(0x04c04305), + 2: Color(0x0be86005), + 3: Color(0x18ff6c03), + 4: Color(0x28ff6e00), + 5: Color(0x3cff6b01), + 6: Color(0x58ff6b01), + 7: Color(0x7eff6601), + 8: Color(0xb1f86300), + 9: Color(0xf7f76300), + 10: Color(0xfaed5b00), + 11: Color(0xfabc4800), + 12: Color(0xee380e00) + }, +); + +const _orangeDark = ColorSwatch( + 0xfff76808, + { + 1: Color(0xff1f1206), + 2: Color(0xff2b1400), + 3: Color(0xff391a03), + 4: Color(0xff441f04), + 5: Color(0xff4f2305), + 6: Color(0xff5f2a06), + 7: Color(0xff763205), + 8: Color(0xff943e00), + 9: Color(0xfff76808), + 10: Color(0xffff802b), + 11: Color(0xffff8b3e), + 12: Color(0xfffeeadd) + }, +); + +const _orangeDarkAlpha = ColorSwatch( + 0xf6ff6b08, + { + 1: Color(0x00000000), + 2: Color(0x0efd3700), + 3: Color(0x1efd5400), + 4: Color(0x2afe6100), + 5: Color(0x37fe6201), + 6: Color(0x49ff6506), + 7: Color(0x63ff6403), + 8: Color(0x85fe6600), + 9: Color(0xf6ff6b08), + 10: Color(0xfaff842c), + 11: Color(0xfaff8c3f), + 12: Color(0xfaffeee1) + }, +); + +const _pink = ColorSwatch( + 0xffd6409f, + { + 1: Color(0xfffffcfe), + 2: Color(0xfffff7fc), + 3: Color(0xfffeeef8), + 4: Color(0xfffce5f3), + 5: Color(0xfff9d8ec), + 6: Color(0xfff3c6e2), + 7: Color(0xffecadd4), + 8: Color(0xffe38ec3), + 9: Color(0xffd6409f), + 10: Color(0xffd23197), + 11: Color(0xffcd1d8d), + 12: Color(0xff3b0a2a) + }, +); + +const _pinkAlpha = ColorSwatch( + 0xbfc8007f, + { + 1: Color(0x03ff05ac), + 2: Color(0x08ff059f), + 3: Color(0x11f00194), + 4: Color(0x1ae2008b), + 5: Color(0x27d80081), + 6: Color(0x39c9017c), + 7: Color(0x52c40079), + 8: Color(0x71c00076), + 9: Color(0xbfc8007f), + 10: Color(0xcec7007e), + 11: Color(0xe2c7007e), + 12: Color(0xf5330021) + }, +); + +const _pinkDark = ColorSwatch( + 0xffd6409f, + { + 1: Color(0xff1f121b), + 2: Color(0xff271421), + 3: Color(0xff3a182f), + 4: Color(0xff451a37), + 5: Color(0xff501b3f), + 6: Color(0xff601d48), + 7: Color(0xff7a1d5a), + 8: Color(0xffa71873), + 9: Color(0xffd6409f), + 10: Color(0xffe34ba9), + 11: Color(0xfff65cb6), + 12: Color(0xfffeebf7) + }, +); + +const _pinkDarkAlpha = ColorSwatch( + 0xd0ff4abd, + { + 1: Color(0x00000000), + 2: Color(0x09fd4ac1), + 3: Color(0x1ffe44c0), + 4: Color(0x2bff41bf), + 5: Color(0x38ff3bc1), + 6: Color(0x4afe38b6), + 7: Color(0x68ff2db5), + 8: Color(0x9bff1cac), + 9: Color(0xd0ff4abd), + 10: Color(0xdfff53bd), + 11: Color(0xf5ff5fbc), + 12: Color(0xfaffeffb) + }, +); + +const _plum = ColorSwatch( + 0xffab4aba, + { + 1: Color(0xfffefcff), + 2: Color(0xfffff8ff), + 3: Color(0xfffceffc), + 4: Color(0xfff9e5f9), + 5: Color(0xfff3d9f4), + 6: Color(0xffebc8ed), + 7: Color(0xffdfafe3), + 8: Color(0xffcf91d8), + 9: Color(0xffab4aba), + 10: Color(0xffa43cb4), + 11: Color(0xff9c2bad), + 12: Color(0xff340c3b) + }, +); + +const _plumAlpha = ColorSwatch( + 0xb589009e, + { + 1: Color(0x03ac05ff), + 2: Color(0x07ff05ff), + 3: Color(0x10d001d0), + 4: Color(0x1ac400c4), + 5: Color(0x26af02b5), + 6: Color(0x37a300ac), + 7: Color(0x509800a6), + 8: Color(0x6e8f00a5), + 9: Color(0xb589009e), + 10: Color(0xc388009d), + 11: Color(0xd488009c), + 12: Color(0xf32a0031) + }, +); + +const _plumDark = ColorSwatch( + 0xffab4aba, + { + 1: Color(0xff1d131d), + 2: Color(0xff251425), + 3: Color(0xff341a34), + 4: Color(0xff3e1d40), + 5: Color(0xff48214b), + 6: Color(0xff542658), + 7: Color(0xff692d6f), + 8: Color(0xff883894), + 9: Color(0xffab4aba), + 10: Color(0xffbd54c6), + 11: Color(0xffd864d8), + 12: Color(0xfffbecfc) + }, +); + +const _plumDarkAlpha = ColorSwatch( + 0xb1ea62ff, + { + 1: Color(0x00000000), + 2: Color(0x09fb2ffb), + 3: Color(0x1afe58fe), + 4: Color(0x28f153ff), + 5: Color(0x34f158fe), + 6: Color(0x43ee5cfe), + 7: Color(0x5dee5aff), + 8: Color(0x86e959ff), + 9: Color(0xb1ea62ff), + 10: Color(0xbff36aff), + 11: Color(0xd3ff75ff), + 12: Color(0xfafff0ff) + }, +); + +const _purple = ColorSwatch( + 0xff8e4ec6, + { + 1: Color(0xfffefcfe), + 2: Color(0xfffdfaff), + 3: Color(0xfff9f1fe), + 4: Color(0xfff3e7fc), + 5: Color(0xffeddbf9), + 6: Color(0xffe3ccf4), + 7: Color(0xffd3b4ed), + 8: Color(0xffbe93e4), + 9: Color(0xff8e4ec6), + 10: Color(0xff8445bc), + 11: Color(0xff793aaf), + 12: Color(0xff2b0e44) + }, +); + +const _purpleAlpha = ColorSwatch( + 0xb15c00ad, + { + 1: Color(0x03ab05ab), + 2: Color(0x059b05ff), + 3: Color(0x0e9200ed), + 4: Color(0x188002e0), + 5: Color(0x248001d5), + 6: Color(0x337500c8), + 7: Color(0x4b6b01c2), + 8: Color(0x6c6600bf), + 9: Color(0xb15c00ad), + 10: Color(0xba5700a3), + 11: Color(0xc5510097), + 12: Color(0xf11f0039) + }, +); + +const _purpleDark = ColorSwatch( + 0xff8e4ec6, + { + 1: Color(0xff1b141d), + 2: Color(0xff221527), + 3: Color(0xff301a3a), + 4: Color(0xff3a1e48), + 5: Color(0xff432155), + 6: Color(0xff4e2667), + 7: Color(0xff5f2d84), + 8: Color(0xff7938b2), + 9: Color(0xff8e4ec6), + 10: Color(0xff9d5bd2), + 11: Color(0xffbf7af0), + 12: Color(0xfff7ecfc) + }, +); + +const _purpleDarkAlpha = ColorSwatch( + 0xbfb561ff, + { + 1: Color(0x00000000), + 2: Color(0x0bb52afb), + 3: Color(0x21bc43fe), + 4: Color(0x31be48fe), + 5: Color(0x3fbc49ff), + 6: Color(0x54b74bff), + 7: Color(0x74b14aff), + 8: Color(0xa8ab4bff), + 9: Color(0xbfb561ff), + 10: Color(0xccbd6dff), + 11: Color(0xeecb81ff), + 12: Color(0xfafcf0ff) + }, +); + +const _red = ColorSwatch( + 0xffe5484d, + { + 1: Color(0xfffffcfc), + 2: Color(0xfffff8f8), + 3: Color(0xffffefef), + 4: Color(0xffffe5e5), + 5: Color(0xfffdd8d8), + 6: Color(0xfff9c6c6), + 7: Color(0xfff3aeaf), + 8: Color(0xffeb9091), + 9: Color(0xffe5484d), + 10: Color(0xffdc3d43), + 11: Color(0xffcd2b31), + 12: Color(0xff381316) + }, +); + +const _redAlpha = ColorSwatch( + 0xb7db0007, + { + 1: Color(0x03ff0505), + 2: Color(0x08ff0505), + 3: Color(0x10ff0101), + 4: Color(0x1aff0000), + 5: Color(0x27f20000), + 6: Color(0x39e40101), + 7: Color(0x51d90004), + 8: Color(0x6fd10004), + 9: Color(0xb7db0007), + 10: Color(0xc2d10007), + 11: Color(0xd4c30007), + 12: Color(0xec280003) + }, +); + +const _redDark = ColorSwatch( + 0xffe5484d, + { + 1: Color(0xff1f1315), + 2: Color(0xff291415), + 3: Color(0xff3c181a), + 4: Color(0xff481a1d), + 5: Color(0xff541b1f), + 6: Color(0xff671e22), + 7: Color(0xff822025), + 8: Color(0xffaa2429), + 9: Color(0xffe5484d), + 10: Color(0xfff2555a), + 11: Color(0xffff6369), + 12: Color(0xfffeecee) + }, +); + +const _redDarkAlpha = ColorSwatch( + 0xe1ff4f55, + { + 1: Color(0x00000000), + 2: Color(0x0bfd2815), + 3: Color(0x21fe3a3d), + 4: Color(0x2ffe3940), + 5: Color(0x3cff353f), + 6: Color(0x52ff353c), + 7: Color(0x71ff303b), + 8: Color(0x9eff2f36), + 9: Color(0xe1ff4f55), + 10: Color(0xf0ff595f), + 11: Color(0xfaff646a), + 12: Color(0xfafff0f2) + }, +); + +const _sage = ColorSwatch( + 0xff8a918e, + { + 1: Color(0xfffbfdfc), + 2: Color(0xfff8faf9), + 3: Color(0xfff1f4f3), + 4: Color(0xffecefed), + 5: Color(0xffe6e9e8), + 6: Color(0xffdfe4e2), + 7: Color(0xffd7dcda), + 8: Color(0xffc2c9c6), + 9: Color(0xff8a918e), + 10: Color(0xff808784), + 11: Color(0xff6a716e), + 12: Color(0xff111c18) + }, +); + +const _sageAlpha = ColorSwatch( + 0x75000f09, + { + 1: Color(0x04058244), + 2: Color(0x07054d29), + 3: Color(0x0e003725), + 4: Color(0x13022a0f), + 5: Color(0x19022117), + 6: Color(0x20012919), + 7: Color(0x28002013), + 8: Color(0x3d011e11), + 9: Color(0x75000f09), + 10: Color(0x7f000e08), + 11: Color(0x95000c07), + 12: Color(0xee000c08) + }, +); + +const _sageDark = ColorSwatch( + 0xff66736d, + { + 1: Color(0xff141716), + 2: Color(0xff191d1b), + 3: Color(0xff1f2421), + 4: Color(0xff252a27), + 5: Color(0xff2a2f2c), + 6: Color(0xff303633), + 7: Color(0xff393f3c), + 8: Color(0xff4a524e), + 9: Color(0xff66736d), + 10: Color(0xff75817b), + 11: Color(0xff99a29e), + 12: Color(0xffeceeed) + }, +); + +const _sageDarkAlpha = ColorSwatch( + 0x65e3fff1, + { + 1: Color(0x00000000), + 2: Color(0x07d4fed6), + 3: Color(0x0fd5fbd7), + 4: Color(0x15e3ffe5), + 5: Color(0x1be8feea), + 6: Color(0x22e5feee), + 7: Color(0x2ceafef2), + 8: Color(0x41e8fef2), + 9: Color(0x65e3fff1), + 10: Color(0x75e8fff3), + 11: Color(0x99f2fff9), + 12: Color(0xecfdfffe) + }, +); + +const _sand = ColorSwatch( + 0xff90908c, + { + 1: Color(0xfffdfdfc), + 2: Color(0xfff9f9f8), + 3: Color(0xfff3f3f2), + 4: Color(0xffeeeeec), + 5: Color(0xffe9e9e6), + 6: Color(0xffe3e3e0), + 7: Color(0xffdbdbd7), + 8: Color(0xffc8c7c1), + 9: Color(0xff90908c), + 10: Color(0xff868682), + 11: Color(0xff706f6c), + 12: Color(0xff1b1b18) + }, +); + +const _sandAlpha = ColorSwatch( + 0x73090900, + { + 1: Color(0x03585805), + 2: Color(0x07292905), + 3: Color(0x0d141400), + 4: Color(0x131c1c02), + 5: Color(0x19212102), + 6: Color(0x1f1a1a01), + 7: Color(0x281a1a00), + 8: Color(0x3e1e1901), + 9: Color(0x73090900), + 10: Color(0x7d090900), + 11: Color(0x93070600), + 12: Color(0xe7040400) + }, +); + +const _sandDark = ColorSwatch( + 0xff717069, + { + 1: Color(0xff161615), + 2: Color(0xff1c1c1a), + 3: Color(0xff232320), + 4: Color(0xff282826), + 5: Color(0xff2e2e2b), + 6: Color(0xff353431), + 7: Color(0xff3e3e3a), + 8: Color(0xff51504b), + 9: Color(0xff717069), + 10: Color(0xff7f7e77), + 11: Color(0xffa1a09a), + 12: Color(0xffededec) + }, +); + +const _sandDarkAlpha = ColorSwatch( + 0x64fffcec, + { + 1: Color(0x00000000), + 2: Color(0x07fdfdd5), + 3: Color(0x0efefeda), + 4: Color(0x14fdfdef), + 5: Color(0x1bfdfde9), + 6: Color(0x22fdf6e6), + 7: Color(0x2cffffec), + 8: Color(0x41fefbea), + 9: Color(0x64fffcec), + 10: Color(0x73fffdee), + 11: Color(0x98fffdf4), + 12: Color(0xebfffffe) + }, +); + +const _sky = ColorSwatch( + 0xff2ebde5, + { + 1: Color(0xfff9feff), + 2: Color(0xfff1fcff), + 3: Color(0xffe4f9ff), + 4: Color(0xffd5f4fd), + 5: Color(0xffc1ecf9), + 6: Color(0xffa4dff1), + 7: Color(0xff79cfea), + 8: Color(0xff2ebde5), + 9: Color(0xff68ddfd), + 10: Color(0xff5fd4f4), + 11: Color(0xff0078a1), + 12: Color(0xff003242) + }, +); + +const _skyAlpha = ColorSwatch( + 0xd100afdf, + { + 1: Color(0x0605d5ff), + 2: Color(0x0e01c8ff), + 3: Color(0x1b01c8ff), + 4: Color(0x2a00baf3), + 5: Color(0x3e01b1e7), + 6: Color(0x5b00a5d8), + 7: Color(0x8600a5d7), + 8: Color(0xd100afdf), + 9: Color(0x9700c5fc), + 10: Color(0xa000baed), + 11: Color(0xfa00759f), + 12: Color(0xfa002e3e) + }, +); + +const _skyDark = ColorSwatch( + 0xff68ddfd, + { + 1: Color(0xff0c1820), + 2: Color(0xff071d2a), + 3: Color(0xff082636), + 4: Color(0xff082d41), + 5: Color(0xff08354c), + 6: Color(0xff083e59), + 7: Color(0xff064b6b), + 8: Color(0xff005d85), + 9: Color(0xff68ddfd), + 10: Color(0xff8ae8ff), + 11: Color(0xff2ec8ee), + 12: Color(0xffeaf8ff) + }, +); + +const _skyDarkAlpha = ColorSwatch( + 0xfa6ae1ff, + { + 1: Color(0x00000000), + 2: Color(0x0b0087fe), + 3: Color(0x1900a5fe), + 4: Color(0x2600a6ff), + 5: Color(0x3200a9fe), + 6: Color(0x4100aefe), + 7: Color(0x5600aefe), + 8: Color(0x7400aeff), + 9: Color(0xfa6ae1ff), + 10: Color(0xfa8decff), + 11: Color(0xec31d6ff), + 12: Color(0xfaeffdff) + }, +); + +const _slate = ColorSwatch( + 0xff889096, + { + 1: Color(0xfffbfcfd), + 2: Color(0xfff8f9fa), + 3: Color(0xfff1f3f5), + 4: Color(0xffeceef0), + 5: Color(0xffe6e8eb), + 6: Color(0xffdfe3e6), + 7: Color(0xffd7dbdf), + 8: Color(0xffc1c8cd), + 9: Color(0xff889096), + 10: Color(0xff7e868c), + 11: Color(0xff687076), + 12: Color(0xff11181c) + }, +); + +const _slateAlpha = ColorSwatch( + 0x7700111e, + { + 1: Color(0x04054482), + 2: Color(0x0705294d), + 3: Color(0x0e002549), + 4: Color(0x13021c37), + 5: Color(0x19021735), + 6: Color(0x20012139), + 7: Color(0x28001a33), + 8: Color(0x3e011e32), + 9: Color(0x7700111e), + 10: Color(0x8100101b), + 11: Color(0x97000e18), + 12: Color(0xee00080c) + }, +); + +const _slateDark = ColorSwatch( + 0xff697177, + { + 1: Color(0xff151718), + 2: Color(0xff1a1d1e), + 3: Color(0xff202425), + 4: Color(0xff26292b), + 5: Color(0xff2b2f31), + 6: Color(0xff313538), + 7: Color(0xff3a3f42), + 8: Color(0xff4c5155), + 9: Color(0xff697177), + 10: Color(0xff787f85), + 11: Color(0xff9ba1a6), + 12: Color(0xffecedee) + }, +); + +const _slateDarkAlpha = ColorSwatch( + 0x69e1f1ff, + { + 1: Color(0x00000000), + 2: Color(0x07d5feff), + 3: Color(0x0fd6fbfc), + 4: Color(0x15e2f0fd), + 5: Color(0x1cdff3fd), + 6: Color(0x23dfeffe), + 7: Color(0x2ee0f3ff), + 8: Color(0x44e5f2fe), + 9: Color(0x69e1f1ff), + 10: Color(0x78e7f3ff), + 11: Color(0x9deff7ff), + 12: Color(0xecfdfeff) + }, +); + +const _teal = ColorSwatch( + 0xff12a594, + { + 1: Color(0xfffafefd), + 2: Color(0xfff1fcfa), + 3: Color(0xffe7f9f5), + 4: Color(0xffd9f3ee), + 5: Color(0xffc7ebe5), + 6: Color(0xffafdfd7), + 7: Color(0xff8dcec3), + 8: Color(0xff53b9ab), + 9: Color(0xff12a594), + 10: Color(0xff0e9888), + 11: Color(0xff067a6f), + 12: Color(0xff10302b) + }, +); + +const _tealAlpha = ColorSwatch( + 0xed009e8c, + { + 1: Color(0x0505cd9b), + 2: Color(0x0e01c8a4), + 3: Color(0x1802c097), + 4: Color(0x2602af8c), + 5: Color(0x3800a489), + 6: Color(0x50009980), + 7: Color(0x7201927a), + 8: Color(0xac009783), + 9: Color(0xed009e8c), + 10: Color(0xf1009281), + 11: Color(0xf900776b), + 12: Color(0xef00221d) + }, +); + +const _tealDark = ColorSwatch( + 0xff12a594, + { + 1: Color(0xff091915), + 2: Color(0xff04201b), + 3: Color(0xff062923), + 4: Color(0xff07312b), + 5: Color(0xff083932), + 6: Color(0xff09443c), + 7: Color(0xff0b544a), + 8: Color(0xff0c6d62), + 9: Color(0xff12a594), + 10: Color(0xff10b3a3), + 11: Color(0xff0ac5b3), + 12: Color(0xffe1faf4) + }, +); + +const _tealDarkAlpha = ColorSwatch( + 0x9b18ffe4, + { + 1: Color(0x00000000), + 2: Color(0x0800fbd5), + 3: Color(0x1200fddc), + 4: Color(0x1b00fde8), + 5: Color(0x2402fee4), + 6: Color(0x3009ffe6), + 7: Color(0x4211ffe3), + 8: Color(0x5d11ffe7), + 9: Color(0x9b18ffe4), + 10: Color(0xab13ffe7), + 11: Color(0xbf0affe7), + 12: Color(0xfae6fff9) + }, +); + +const _tomato = ColorSwatch( + 0xffe54d2e, + { + 1: Color(0xfffffcfc), + 2: Color(0xfffff8f7), + 3: Color(0xfffff0ee), + 4: Color(0xffffe6e2), + 5: Color(0xfffdd8d3), + 6: Color(0xfffac7be), + 7: Color(0xfff3b0a2), + 8: Color(0xffea9280), + 9: Color(0xffe54d2e), + 10: Color(0xffdb4324), + 11: Color(0xffca3214), + 12: Color(0xff341711) + }, +); + +const _tomatoAlpha = ColorSwatch( + 0xd1df2500, + { + 1: Color(0x03ff0505), + 2: Color(0x08ff2605), + 3: Color(0x11ff1f01), + 4: Color(0x1dff2201), + 5: Color(0x2cf41d01), + 6: Color(0x41ec2300), + 7: Color(0x5dde2500), + 8: Color(0x7fd52401), + 9: Color(0xd1df2500), + 10: Color(0xdbd52400), + 11: Color(0xebc62100), + 12: Color(0xee260600) + }, +); + +const _tomatoDark = ColorSwatch( + 0xffe54d2e, + { + 1: Color(0xff1d1412), + 2: Color(0xff2a1410), + 3: Color(0xff3b1813), + 4: Color(0xff481a14), + 5: Color(0xff541c15), + 6: Color(0xff652016), + 7: Color(0xff7f2315), + 8: Color(0xffa42a12), + 9: Color(0xffe54d2e), + 10: Color(0xffec5e41), + 11: Color(0xfff16a50), + 12: Color(0xfffeefec) + }, +); + +const _tomatoDarkAlpha = ColorSwatch( + 0xe2ff5431, + { + 1: Color(0x00000000), + 2: Color(0x0ffd1500), + 3: Color(0x22ff3019), + 4: Color(0x31fe331c), + 5: Color(0x3efe351e), + 6: Color(0x51ff391e), + 7: Color(0x6fff3719), + 8: Color(0x98ff3a12), + 9: Color(0xe2ff5431), + 10: Color(0xeaff6445), + 11: Color(0xefff7054), + 12: Color(0xfafff3f0) + }, +); + +const _violet = ColorSwatch( + 0xff6e56cf, + { + 1: Color(0xfffdfcfe), + 2: Color(0xfffbfaff), + 3: Color(0xfff5f2ff), + 4: Color(0xffede9fe), + 5: Color(0xffe4defc), + 6: Color(0xffd7cff9), + 7: Color(0xffc4b8f3), + 8: Color(0xffaa99ec), + 9: Color(0xff6e56cf), + 10: Color(0xff644fc1), + 11: Color(0xff5746af), + 12: Color(0xff20134b) + }, +); + +const _violetAlpha = ColorSwatch( + 0xa92500b6, + { + 1: Color(0x035805ab), + 2: Color(0x053705ff), + 3: Color(0x0d3c00ff), + 4: Color(0x162e02f4), + 5: Color(0x212f01e8), + 6: Color(0x302a01df), + 7: Color(0x472b01d4), + 8: Color(0x662a00d0), + 9: Color(0xa92500b6), + 10: Color(0xb01f00a5), + 11: Color(0xb9180091), + 12: Color(0xec0e003d) + }, +); + +const _violetDark = ColorSwatch( + 0xff6e56cf, + { + 1: Color(0xff17151f), + 2: Color(0xff1c172b), + 3: Color(0xff251e40), + 4: Color(0xff2c2250), + 5: Color(0xff32275f), + 6: Color(0xff392c72), + 7: Color(0xff443592), + 8: Color(0xff5842c3), + 9: Color(0xff6e56cf), + 10: Color(0xff7c66dc), + 11: Color(0xff9e8cfc), + 12: Color(0xfff1eefe) + }, +); + +const _violetDarkAlpha = ColorSwatch( + 0xc88668ff, + { + 1: Color(0x00000000), + 2: Color(0x0e743afd), + 3: Color(0x267452fe), + 4: Color(0x387650ff), + 5: Color(0x497654ff), + 6: Color(0x5f7253ff), + 7: Color(0x837053ff), + 8: Color(0xbb6f52ff), + 9: Color(0xc88668ff), + 10: Color(0xd78e75ff), + 11: Color(0xfaa18eff), + 12: Color(0xfaf5f2ff) + }, +); + +const _whiteAlpha = ColorSwatch( + 0xebffffff, + { + 1: Color(0x00ffffff), + 2: Color(0x03ffffff), + 3: Color(0x09ffffff), + 4: Color(0x0effffff), + 5: Color(0x16ffffff), + 6: Color(0x20ffffff), + 7: Color(0x2dffffff), + 8: Color(0x3fffffff), + 9: Color(0x62ffffff), + 10: Color(0x72ffffff), + 11: Color(0x97ffffff), + 12: Color(0xebffffff) + }, +); + +const _yellow = ColorSwatch( + 0xffebbc00, + { + 1: Color(0xfffdfdf9), + 2: Color(0xfffffce8), + 3: Color(0xfffffbd1), + 4: Color(0xfffff8bb), + 5: Color(0xfffef2a4), + 6: Color(0xfff9e68c), + 7: Color(0xffefd36c), + 8: Color(0xffebbc00), + 9: Color(0xfff5d90a), + 10: Color(0xfff7ce00), + 11: Color(0xff946800), + 12: Color(0xff35290f) + }, +); + +const _yellowAlpha = ColorSwatch( + 0xfaebbc00, + { + 1: Color(0x06abab05), + 2: Color(0x17ffdd02), + 3: Color(0x2effea01), + 4: Color(0x44ffe601), + 5: Color(0x5bfcdb00), + 6: Color(0x73f2c900), + 7: Color(0x93e3b200), + 8: Color(0xfaebbc00), + 9: Color(0xf5f5d800), + 10: Color(0xfaf7ce00), + 11: Color(0xfa926600), + 12: Color(0xf0291c00) + }, +); + +const _yellowDark = ColorSwatch( + 0xfff5d90a, + { + 1: Color(0xff1c1500), + 2: Color(0xff221a00), + 3: Color(0xff2c2100), + 4: Color(0xff352800), + 5: Color(0xff3e3000), + 6: Color(0xff493c00), + 7: Color(0xff594a05), + 8: Color(0xff705e00), + 9: Color(0xfff5d90a), + 10: Color(0xffffef5c), + 11: Color(0xfff0c000), + 12: Color(0xfffffad1) + }, +); + +const _yellowDarkAlpha = ColorSwatch( + 0xf4ffe20a, + { + 1: Color(0x00000000), + 2: Color(0x07facd00), + 3: Color(0x12fdbe00), + 4: Color(0x1cfdc200), + 5: Color(0x26fec700), + 6: Color(0x33fed800), + 7: Color(0x45ffdb13), + 8: Color(0x5ffed800), + 9: Color(0xf4ffe20a), + 10: Color(0xfafff45e), + 11: Color(0xeeffcc00), + 12: Color(0xfaffffd5) + }, +); diff --git a/packages/remix/lib/helpers/color_utils.dart b/packages/remix/lib/helpers/color_utils.dart new file mode 100644 index 000000000..968eab390 --- /dev/null +++ b/packages/remix/lib/helpers/color_utils.dart @@ -0,0 +1,106 @@ +import 'dart:math' as math; + +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; + +extension ColorUtilityX on ColorUtility { + T alphaBlend(Color foreground, Color background) => + call(Color.alphaBlend(foreground, background)); +} + +double _calculateContrast(Color backgroundColor, Color textColor) { + /// Calculates the contrast ratio between two colors. + /// + /// The contrast ratio is a measure of the perceived difference in brightness + /// between the text color and the background color. A higher ratio indicates + /// better readability. + /// + /// The calculation involves: + /// 1. Computing the relative luminance of each color. + /// 2. Finding the lighter (brightest) and darker (darkest) colors. + /// 3. Applying the contrast ratio formula: (brightest + 0.05) / (darkest + 0.05) + /// + /// Note: Relative luminance calculation is computationally expensive. + var lum1 = textColor.computeLuminance(); + var lum2 = backgroundColor.computeLuminance(); + + var brightest = math.max(lum1, lum2); + var darkest = math.min(lum1, lum2); + + return (brightest + 0.05) / (darkest + 0.05); +} + +class RXColor { + final Color color; + final ColorSwatch swatch; + + RXColor(this.color) : swatch = getColorSwatch(color); + + Color get shade50 => swatch[50]!; + Color get shade100 => swatch[100]!; + Color get shade200 => swatch[200]!; + Color get shade300 => swatch[300]!; + Color get shade400 => swatch[400]!; + Color get shade500 => swatch[500]!; + Color get shade600 => swatch[600]!; + Color get shade700 => swatch[700]!; + Color get shade800 => swatch[800]!; + Color get shade900 => swatch[900]!; +} + +ColorSwatch getColorSwatch(Color color) { + final hslColor = HSLColor.fromColor(color); + final lightness = hslColor.lightness; + + /// if [500] is the default color, there are at LEAST five + /// steps below [500]. (i.e. 400, 300, 200, 100, 50.) A + /// divisor of 5 would mean [50] is a lightness of 1.0 or + /// a color of #ffffff. A value of six would be near white + /// but not quite. + const lowDivisor = 6; + + /// if [500] is the default color, there are at LEAST four + /// steps above [500]. A divisor of 4 would mean [900] is + /// a lightness of 0.0 or color of #000000 + const highDivisor = 5; + + final lowStep = (1.0 - lightness) / lowDivisor; + final highStep = lightness / highDivisor; + + return ColorSwatch(color.value, { + 50: (hslColor.withLightness(lightness + (lowStep * 5))).toColor(), + 100: (hslColor.withLightness(lightness + (lowStep * 4))).toColor(), + 200: (hslColor.withLightness(lightness + (lowStep * 3))).toColor(), + 300: (hslColor.withLightness(lightness + (lowStep * 2))).toColor(), + 400: (hslColor.withLightness(lightness + lowStep)).toColor(), + 500: (hslColor.withLightness(lightness)).toColor(), + 600: (hslColor.withLightness(lightness - highStep)).toColor(), + 700: (hslColor.withLightness(lightness - (highStep * 2))).toColor(), + 800: (hslColor.withLightness(lightness - (highStep * 3))).toColor(), + 900: (hslColor.withLightness(lightness - (highStep * 4))).toColor(), + }); +} + +Color getTextColor(Color background) { + const white = Color(0xFFFFFFFF); + + final contrastRatio = _calculateContrast(white, background); + + if (contrastRatio <= 4.5) { + final hslBackground = HSLColor.fromColor(background); + final lightness = hslBackground.lightness; + final saturation = hslBackground.saturation; + final hue = hslBackground.hue; + + final adjustedLightness = lightness < 0.5 ? 0.95 : 0.05; + + return HSLColor.fromAHSL( + 1.0, + hue, + saturation * 0.08, + adjustedLightness, + ).toColor(); + } + + return white; +} diff --git a/packages/remix/lib/helpers/context_ext.dart b/packages/remix/lib/helpers/context_ext.dart new file mode 100644 index 000000000..d4d559a5e --- /dev/null +++ b/packages/remix/lib/helpers/context_ext.dart @@ -0,0 +1,6 @@ +import 'package:flutter/material.dart'; + +extension BuildContextX on BuildContext { + bool get isDarkMode => Theme.of(this).brightness == Brightness.dark; + bool get isLightMode => Theme.of(this).brightness == Brightness.light; +} diff --git a/packages/remix/lib/helpers/utility_extension.dart b/packages/remix/lib/helpers/utility_extension.dart new file mode 100644 index 000000000..a1687f269 --- /dev/null +++ b/packages/remix/lib/helpers/utility_extension.dart @@ -0,0 +1,5 @@ +import 'package:mix/mix.dart'; + +extension BoxSpecUtilityX on BoxSpecUtility { + T size(double value) => only(height: value, width: value); +} diff --git a/packages/remix/lib/helpers/variant.dart b/packages/remix/lib/helpers/variant.dart new file mode 100644 index 000000000..6a2ed75cb --- /dev/null +++ b/packages/remix/lib/helpers/variant.dart @@ -0,0 +1,7 @@ +import 'package:mix/mix.dart'; + +abstract class RemixVariant extends Variant { + const RemixVariant(String name) : super('remix.$name'); + + String get label => name.split('.').last; +} diff --git a/packages/remix/lib/remix.dart b/packages/remix/lib/remix.dart new file mode 100644 index 000000000..26ab54451 --- /dev/null +++ b/packages/remix/lib/remix.dart @@ -0,0 +1,26 @@ +library remix; + +export 'components/button/button_spec.dart'; +export 'components/button/button_style.dart'; +export 'components/button/button_variants.dart'; +export 'components/button/button_widget.dart'; +export 'components/card/card_spec.dart'; +export 'components/card/card_style.dart'; +export 'components/card/card_variants.dart'; +export 'components/card/card_widget.dart'; +export 'components/checkbox/checkbox_spec.dart'; +export 'components/checkbox/checkbox_style.dart'; +export 'components/checkbox/checkbox_variants.dart'; +export 'components/checkbox/checkbox_widget.dart'; +export 'components/radio/radio_spec.dart'; +export 'components/radio/radio_style.dart'; +export 'components/radio/radio_variants.dart'; +export 'components/spinner/spinner.style.dart'; +export 'components/spinner/spinner.variants.dart'; +export 'components/spinner/spinner_spec.dart'; +export 'components/spinner/spinner_widget.dart'; +export 'components/switch/switch_spec.dart'; +export 'components/switch/switch_style.dart'; +export 'components/switch/switch_variants.dart'; +export 'components/switch/switch_widget.dart'; +export 'tokens/remix_tokens.dart'; diff --git a/packages/remix/lib/tokens/color_tokens.dart b/packages/remix/lib/tokens/color_tokens.dart new file mode 100644 index 000000000..fb20539dc --- /dev/null +++ b/packages/remix/lib/tokens/color_tokens.dart @@ -0,0 +1,64 @@ +import 'package:flutter/rendering.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/helpers/color_palette.dart'; + +class RemixColor { + const RemixColor(this.value); + + final Color value; +} + +class RemixColors { + RemixColors(); + + final _blackColor = const ColorToken('--black'); + final _whiteColor = const ColorToken('--white'); + final _accentSwatch = ColorSwatchToken.scale('--accent', 12); + final _accentAlphaSwatch = ColorSwatchToken.scale('--accent-alpha', 12); + + final _neutralSwatch = ColorSwatchToken.scale('--neutral', 12); + final _neutralAlphaSwatch = ColorSwatchToken.scale('--neutral-alpha', 12); + + ColorToken black() => _blackColor; + ColorToken white() => _whiteColor; + ColorToken accent([int? step]) { + return step == null ? _accentSwatch : _accentSwatch[step]; + } + + ColorToken accentAlpha([int? step]) { + return step == null ? _accentAlphaSwatch : _accentAlphaSwatch[step]; + } + + ColorToken neutral([int? step]) { + return step == null ? _neutralSwatch : _neutralSwatch[step]; + } + + ColorToken neutralAlpha([int? step]) { + return step == null ? _neutralAlphaSwatch : _neutralAlphaSwatch[step]; + } +} + +Map _mapColorRadixTokens({ + required RadixColors accent, + required RadixColors neutral, +}) { + final remix = RemixColors(); + + return { + remix._whiteColor: const Color(0xFFFFFFFF), + remix._blackColor: const Color(0xFF1C2024), + remix._accentSwatch: accent.swatch, + remix._accentAlphaSwatch: accent.alphaSwatch, + remix._neutralSwatch: neutral.swatch, + remix._neutralAlphaSwatch: neutral.alphaSwatch, + }; +} + +final remixColorTokens = _mapColorRadixTokens( + accent: RadixColors.indigo, + neutral: RadixColors.slate, +); +final remixDarkColorTokens = _mapColorRadixTokens( + accent: RadixColors.indigoDark, + neutral: RadixColors.slateDark, +); diff --git a/packages/remix/lib/tokens/radius_tokens.dart b/packages/remix/lib/tokens/radius_tokens.dart new file mode 100644 index 000000000..1d4bdfb0e --- /dev/null +++ b/packages/remix/lib/tokens/radius_tokens.dart @@ -0,0 +1,23 @@ +import 'package:flutter/rendering.dart'; +import 'package:mix/mix.dart'; + +class RemixRadius { + RemixRadius(); + + final radius1 = const RadiusToken('--radius-1'); + final radius2 = const RadiusToken('--radius-2'); + final radius3 = const RadiusToken('--radius-3'); + final radius4 = const RadiusToken('--radius-4'); + final radius5 = const RadiusToken('--radius-5'); + final radius6 = const RadiusToken('--radius-6'); +} + +final _r = RemixRadius(); +final remixRadiusTokens = { + _r.radius1: const Radius.circular(4), + _r.radius2: const Radius.circular(8), + _r.radius3: const Radius.circular(12), + _r.radius4: const Radius.circular(16), + _r.radius5: const Radius.circular(24), + _r.radius6: const Radius.circular(32), +}; diff --git a/packages/remix/lib/tokens/remix_tokens.dart b/packages/remix/lib/tokens/remix_tokens.dart new file mode 100644 index 000000000..24de66fca --- /dev/null +++ b/packages/remix/lib/tokens/remix_tokens.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix/tokens/color_tokens.dart'; +import 'package:remix/tokens/radius_tokens.dart'; +import 'package:remix/tokens/space_tokens.dart'; +import 'package:remix/tokens/text_style_tokens.dart'; + +final $rx = _RemixTokenRef(); + +class _RemixTokenRef { + _RemixTokenRef(); + final color = RemixColors(); + + final space = RemixSpace(); + + final radii = RemixRadius(); + + final text = RemixTypography(); +} + +final _baseRemixTokens = MixThemeData( + colors: remixColorTokens, + textStyles: remixTextTokens, + spaces: remixSpaceTokens, + radii: remixRadiusTokens, +); + +final _lightRemixTokens = _baseRemixTokens; +final _darkRemixTokens = _baseRemixTokens.copyWith( + colors: remixDarkColorTokens, +); + +class RemixTokens extends StatelessWidget { + const RemixTokens({super.key, required this.child, required this.data}); + + final Widget child; + + final MixThemeData data; + + static MixThemeData light = _lightRemixTokens; + static MixThemeData dark = _darkRemixTokens; + + @override + Widget build(BuildContext context) { + return MixTheme( + data: data, + child: child, + ); + } +} diff --git a/packages/remix/lib/tokens/space_tokens.dart b/packages/remix/lib/tokens/space_tokens.dart new file mode 100644 index 000000000..de2435ed6 --- /dev/null +++ b/packages/remix/lib/tokens/space_tokens.dart @@ -0,0 +1,59 @@ +import 'package:mix/mix.dart'; + +class RemixSpace { + RemixSpace(); + + final space1 = const SpaceToken('--space-1'); + final space2 = const SpaceToken('--space-2'); + final space3 = const SpaceToken('--space-3'); + final space4 = const SpaceToken('--space-4'); + final space5 = const SpaceToken('--space-5'); + final space6 = const SpaceToken('--space-6'); + final space7 = const SpaceToken('--space-7'); + final space8 = const SpaceToken('--space-8'); + final space9 = const SpaceToken('--space-9'); + + operator [](int index) { + return call(index); + } + + SpaceToken call(int step) { + switch (step) { + case 1: + return space1; + case 2: + return space2; + case 3: + return space3; + case 4: + return space4; + case 5: + return space5; + case 6: + return space6; + case 7: + return space7; + case 8: + return space8; + case 9: + return space9; + default: + throw Exception( + 'Invalid space step: $step found. Space step should be between 1 and 9.', + ); + } + } +} + +final _s = RemixSpace(); +final remixSpaceTokens = { + _s.space1: 4, + _s.space2: 8, + _s.space3: 12, + _s.space4: 16, + _s.space5: 24, + _s.space6: 32, + _s.space7: 40, + _s.space8: 48, + _s.space9: 64, +}; diff --git a/packages/remix/lib/tokens/text_style_tokens.dart b/packages/remix/lib/tokens/text_style_tokens.dart new file mode 100644 index 000000000..90c32f5dd --- /dev/null +++ b/packages/remix/lib/tokens/text_style_tokens.dart @@ -0,0 +1,65 @@ +import 'package:flutter/widgets.dart'; +import 'package:mix/mix.dart'; + +class RemixTypography { + RemixTypography(); + + final text1 = const TextStyleToken('--text-1'); + final text2 = const TextStyleToken('--text-2'); + final text3 = const TextStyleToken('--text-3'); + final text4 = const TextStyleToken('--text-4'); + final text5 = const TextStyleToken('--text-5'); + final text6 = const TextStyleToken('--text-6'); + final text7 = const TextStyleToken('--text-7'); + final text8 = const TextStyleToken('--text-8'); + final text9 = const TextStyleToken('--text-9'); +} + +final _t = RemixTypography(); +final remixTextTokens = { + _t.text1: const TextStyle( + fontSize: 12, + letterSpacing: 0.0025, + height: 1.33, + ), + _t.text2: const TextStyle( + fontSize: 14, + letterSpacing: 0, + height: 1.43, + ), + _t.text3: const TextStyle( + fontSize: 16, + letterSpacing: 0, + height: 1.50, + ), + _t.text4: const TextStyle( + fontSize: 18, + letterSpacing: -0.0025, + height: 1.44, + ), + _t.text5: const TextStyle( + fontSize: 20, + letterSpacing: -0.005, + height: 1.40, + ), + _t.text6: const TextStyle( + fontSize: 24, + letterSpacing: -0.00625, + height: 1.25, + ), + _t.text7: const TextStyle( + fontSize: 28, + letterSpacing: -0.0075, + height: 1.29, + ), + _t.text8: const TextStyle( + fontSize: 35, + letterSpacing: -0.01, + height: 1.14, + ), + _t.text9: const TextStyle( + fontSize: 60, + letterSpacing: -0.025, + height: 1.00, + ), +}; diff --git a/packages/remix/macos/Flutter/GeneratedPluginRegistrant.swift b/packages/remix/macos/Flutter/GeneratedPluginRegistrant.swift new file mode 100644 index 000000000..cccf817a5 --- /dev/null +++ b/packages/remix/macos/Flutter/GeneratedPluginRegistrant.swift @@ -0,0 +1,10 @@ +// +// Generated file. Do not edit. +// + +import FlutterMacOS +import Foundation + + +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { +} diff --git a/packages/remix/macos/Flutter/ephemeral/Flutter-Generated.xcconfig b/packages/remix/macos/Flutter/ephemeral/Flutter-Generated.xcconfig new file mode 100644 index 000000000..8e5ab25f5 --- /dev/null +++ b/packages/remix/macos/Flutter/ephemeral/Flutter-Generated.xcconfig @@ -0,0 +1,11 @@ +// This is a generated file; do not edit or check into version control. +FLUTTER_ROOT=/Users/leofarias/fvm/versions/3.19.0 +FLUTTER_APPLICATION_PATH=/Users/leofarias/Projects/mix/packages/remix +COCOAPODS_PARALLEL_CODE_SIGN=true +FLUTTER_BUILD_DIR=build +FLUTTER_BUILD_NAME=0.0.1 +FLUTTER_BUILD_NUMBER=0.0.1 +DART_OBFUSCATION=false +TRACK_WIDGET_CREATION=true +TREE_SHAKE_ICONS=false +PACKAGE_CONFIG=.dart_tool/package_config.json diff --git a/packages/remix/macos/Flutter/ephemeral/flutter_export_environment.sh b/packages/remix/macos/Flutter/ephemeral/flutter_export_environment.sh new file mode 100755 index 000000000..54c982787 --- /dev/null +++ b/packages/remix/macos/Flutter/ephemeral/flutter_export_environment.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# This is a generated file; do not edit or check into version control. +export "FLUTTER_ROOT=/Users/leofarias/fvm/versions/3.19.0" +export "FLUTTER_APPLICATION_PATH=/Users/leofarias/Projects/mix/packages/remix" +export "COCOAPODS_PARALLEL_CODE_SIGN=true" +export "FLUTTER_BUILD_DIR=build" +export "FLUTTER_BUILD_NAME=0.0.1" +export "FLUTTER_BUILD_NUMBER=0.0.1" +export "DART_OBFUSCATION=false" +export "TRACK_WIDGET_CREATION=true" +export "TREE_SHAKE_ICONS=false" +export "PACKAGE_CONFIG=.dart_tool/package_config.json" diff --git a/packages/remix/pubspec.yaml b/packages/remix/pubspec.yaml new file mode 100644 index 000000000..d198dc789 --- /dev/null +++ b/packages/remix/pubspec.yaml @@ -0,0 +1,24 @@ +name: remix +description: Completely unstyled, widgets designed to integrate with Mix + +version: 0.0.1 + +environment: + sdk: ">=3.3.0 <4.0.0" + +dependencies: + flutter: + sdk: flutter + mix: ^1.1.2 + mix_annotations: ^0.1.0 + +dev_dependencies: + flutter_test: + sdk: flutter + + flutter_lints: ^2.0.0 + mix_generator: ^0.1.2 + build_runner: ^2.4.9 + +flutter: + uses-material-design: true diff --git a/packages/remix/scripts/generate.dart b/packages/remix/scripts/generate.dart new file mode 100644 index 000000000..0b7d48156 --- /dev/null +++ b/packages/remix/scripts/generate.dart @@ -0,0 +1,53 @@ +import 'dart:io'; + +void main(List arguments) { + if (arguments.isEmpty) { + print('Please provide a component name as an argument.'); + return; + } + + final componentName = arguments[0]; + + generateSpecFile(componentName); + generateWidgetFile(componentName); + generateStyleFile(componentName); + generateVariantsFile(componentName); + + print('Files generated successfully!'); +} + +void generateSpecFile(String componentName) { + final directory = 'lib/components/$componentName'; + final fileName = '$directory/${componentName}_spec.dart'; + const content = ''; + + Directory(directory).createSync(recursive: true); + File(fileName).writeAsStringSync(content); +} + +void generateWidgetFile(String componentName) { + final directory = 'lib/components/$componentName'; + final fileName = '$directory/${componentName}_widget.dart'; + const content = ''; + + Directory(directory).createSync(recursive: true); + File(fileName).writeAsStringSync(content); +} + +void generateStyleFile(String componentName) { + final directory = 'lib/components/$componentName'; + final fileName = '$directory/$componentName.style.dart'; + const content = ''; + + Directory(directory).createSync(recursive: true); + File(fileName).writeAsStringSync(content); +} + +void generateVariantsFile(String componentName) { + final directory = 'lib/components/$componentName'; + final fileName = '$directory/$componentName.variants.dart'; + const content = ''; + + Directory(directory).createSync(recursive: true); + File(fileName).writeAsStringSync(content); +} diff --git a/packages/remix/scripts/markdown.dart b/packages/remix/scripts/markdown.dart new file mode 100644 index 000000000..41905042c --- /dev/null +++ b/packages/remix/scripts/markdown.dart @@ -0,0 +1,28 @@ +import 'dart:io'; + +void main() { + final rootDirectory = Directory.current; + final contextFile = File('context.md'); + + void processDirectory(Directory directory) { + for (var fileOrDir in directory.listSync()) { + if (fileOrDir is File && + fileOrDir.path.endsWith('.dart') && + !fileOrDir.path.endsWith('.g.dart')) { + final fileName = fileOrDir.path.split('/').last; + final fileContent = fileOrDir.readAsStringSync(); + + contextFile.writeAsStringSync('# $fileName\n', mode: FileMode.append); + contextFile.writeAsStringSync('```dart\n', mode: FileMode.append); + contextFile.writeAsStringSync(fileContent, mode: FileMode.append); + contextFile.writeAsStringSync('\n```\n', mode: FileMode.append); + } else if (fileOrDir is Directory) { + processDirectory(fileOrDir); + } + } + } + + contextFile.writeAsStringSync('# Dart Files\n'); + processDirectory(rootDirectory); + print('context.md file generated successfully.'); +} diff --git a/packages/remix/test/components/button_test.dart b/packages/remix/test/components/button_test.dart new file mode 100644 index 000000000..9b12a080e --- /dev/null +++ b/packages/remix/test/components/button_test.dart @@ -0,0 +1,96 @@ +void main() { + // group('RemixButton', () { + // testWidgets('renders with correct label', (WidgetTester tester) async { + // const label = 'Test Button'; + // await tester.pumpWidget( + // MaterialApp( + // home: RxButton(label: label, onPressed: () {}), + // ), + // ); + + // expect( + // find.byWidgetPredicate( + // (widget) => widget is Text && widget.data == label, + // ), + // findsOneWidget, + // ); + // }); + + // testWidgets('shows loading indicator and label when isLoading is true', + // (WidgetTester tester) async { + // const loadingLabel = 'Loading...'; + + // await tester.pumpWidget( + // MaterialApp( + // home: RxButton( + // label: 'Test Button', + // loading: true, + // onPressed: () {}, + // ), + // ), + // ); + + // expect(find.byType(CircularProgressIndicator), findsOneWidget); + // expect(find.text(loadingLabel), findsOneWidget); + // }); + + // testWidgets('displays correct icons when provided', + // (WidgetTester tester) async { + // await tester.pumpWidget(MaterialApp( + // home: RxButton( + // label: 'Test Button', + // iconLeft: Icons.arrow_back, + // iconRight: Icons.arrow_forward, + // onPressed: () {}, + // ), + // )); + + // expect(find.byIcon(Icons.arrow_back), findsOneWidget); + // expect(find.byIcon(Icons.arrow_forward), findsOneWidget); + + // final HBox iconRow = tester.widget(find.byType(HBox)); + // expect(iconRow.children.first, isInstanceOf()); + // expect((iconRow.children.first as StyledIcon).icon, Icons.arrow_back); + // expect(iconRow.children.last, isInstanceOf()); + // expect((iconRow.children.last as StyledIcon).icon, Icons.arrow_forward); + // }); + // }); + + // testWidgets('when disabled must not call onPressed', + // (WidgetTester tester) async { + // bool didCallOnPressed = false; + + // await tester.pumpWidget(MaterialApp( + // home: RxButton( + // label: 'Disabled Button', + // onPressed: () { + // didCallOnPressed = true; + // }, + // disabled: true, + // ), + // )); + + // await tester.tap(find.byType(RxButton)); + // await tester.pumpAndSettle(const Duration(milliseconds: 200)); + + // expect(didCallOnPressed, false); + // }); + + // testWidgets('when enabled must call onPressed', (WidgetTester tester) async { + // bool didCallOnPressed = false; + + // await tester.pumpWidget(MaterialApp( + // home: RxButton( + // label: 'Disabled Button', + // onPressed: () { + // didCallOnPressed = true; + // }, + // ), + // )); + + // await tester.tap(find.byType(RxButton)); + // await tester.pumpAndSettle(const Duration(milliseconds: 200)); + + // expect(didCallOnPressed, isTrue); + // }); +} diff --git a/website/.gitignore b/website/.gitignore index fbea7fded..636b6426d 100644 --- a/website/.gitignore +++ b/website/.gitignore @@ -2,6 +2,4 @@ node_modules .next .DS_Store yarn-error.log -dist -examples -packages \ No newline at end of file +dist \ No newline at end of file diff --git a/website/pages/docs/tutorials/custom-component.mdx b/website/pages/docs/tutorials/custom-component.mdx new file mode 100644 index 000000000..ed462b3e8 --- /dev/null +++ b/website/pages/docs/tutorials/custom-component.mdx @@ -0,0 +1,272 @@ + + +import { Callout } from "nextra-theme-docs"; + +# Building Custom Design System Component + +Mix is a powerful tool, and to make it even more powerful, we can add support for new widgets and increase its functionality for more and more use cases. Therefore, this guide will help you add support for new widgets. + +To make this tutorial more practical, we will add support for a widget from `Material`, the TextField. Specifically, we will add support for the `decoration` attribute, which defines most of the visual aspects of the TextField. As a result, we will be able to go from the default TextField, which looks like this: + + + +## 1. Define the Spec + +As we are adding support for a new widget and its attributes that you want to customize, we need to define the spec for it. The spec is an object that defines the attributes the widget has and how to handle them. The spec for the `InputDecoration` is: + +```dart +class InputDecorationSpec extends Spec { + final InputBorder? border; + final bool? filled; + final Color? fillColor; + final EdgeInsetsGeometry? contentPadding; + + const InputDecorationSpec({ + this.border, + this.filled, + this.fillColor, + this.contentPadding, + }); + + const InputDecorationSpec.empty() + : border = null, + filled = null, + fillColor = null, + contentPadding = null; + + static InputDecorationSpec of(BuildContext context) { + final mix = Mix.of(context); + return mix.attributeOf()?.resolve(mix) ?? + const InputDecorationSpec.empty(); + } + + @override + InputDecorationSpec lerp(InputDecorationSpec? other, double t) { + return InputDecorationSpec( + border: other?.border, + filled: t < 0.5 ? filled : other?.filled, + fillColor: Color.lerp(fillColor, other?.fillColor, t), + contentPadding: EdgeInsetsGeometry.lerp( + contentPadding, + other?.contentPadding, + t, + ), + ); + } + + InputDecorationSpec copyWith({ + InputBorder? border, + bool? filled, + Color? fillColor, + EdgeInsetsGeometry? contentPadding, + }) { + return InputDecorationSpec( + border: border ?? this.border, + filled: filled ?? this.filled, + fillColor: fillColor ?? this.fillColor, + contentPadding: contentPadding ?? this.contentPadding, + ); + } + + @override + get props => [ + border, + filled, + fillColor, + contentPadding, + ]; +} +``` + +At first glance, it may seem a bit complex, but it's not. The `InputDecorationSpec` is a class that extends `Spec` and has a constructor that receives the attributes of the `InputDecoration`. For this example, I chose just four attributes: `border`, `filled`, `fillColor`, and `contentPadding`. However, for a real implementation, you should add all the attributes that the `InputDecoration` has. + +Looking at the rest of the class, you can see the named constructor `empty`, which returns a default implementation of the `InputDecorationSpec`, the `of` method that receives a `MixData` and returns an `InputDecorationSpec` with the values of the `MixData`. The `lerp` method is used to interpolate between two `InputDecorationSpec` instances. + +The Spec is the base for supporting a new widget and its attributes. + +## 2. Create the Attribute + +The attribute is the class that will be used to handle the `InputDecorationSpec`. The `InputDecorationSpecAttribute` is: + +```dart +class InputDecorationSpecAttribute extends SpecAttribute { + final InputBorder? border; + final bool? filled; + final ColorDto? fillColor; + final SpacingDto? contentPadding; + + const InputDecorationSpecAttribute({ + this.border, + this.filled, + this.fillColor, + this.contentPadding, + }); + + @override + InputDecorationSpec resolve(MixData mix) { + return InputDecorationSpec( + border: border, + filled: filled, + fillColor: fillColor?.resolve(mix), + contentPadding: contentPadding?.resolve(mix), + ); + } + + @override + InputDecorationSpecAttribute merge( + covariant InputDecorationSpecAttribute? other) { + if (other == null) return this; + + return InputDecorationSpecAttribute( + border: other.border ?? border, + filled: other.filled ?? filled, + fillColor: other.fillColor ?? fillColor, + contentPadding: other.contentPadding ?? contentPadding, + ); + } + + @override + get props => [ + border, + filled, + fillColor, + contentPadding, + ]; +} + +``` + +Looking at the properties' definition, you will see some changes in the property types. For example, now `fillColor` is a `ColorDto`, and `contentPadding` is a `SpacingDto`. This is because the Mix uses `Dto` classes to handle more complex types and provide facilities to use them. + +The `InputDecorationSpecAttribute` is a class that extends `SpecAttribute` and has a `resolve` method, which is a useful method to transform the `InputDecorationSpec` from the `MixData`. The `merge` method is used to merge two different declarations of the `InputDecorationSpecAttribute`. A good example of this is: + +```dart +final style = Style( + InputDecorationSpecAttribute( + border: OutlineInputBorder(), + fillColor: ColorDto(Colors.blue), + filled: true, + ), + InputDecorationSpecAttribute( + fillColor: ColorDto(Colors.red), + contentPadding: SpacingDto.only(top: 10), + ), +) +``` + +In this case, the `style` will have the `border` and `filled` from the first declaration, and the `fillColor` and `contentPadding` from the second declaration. Be aware that the second declaration of `fillColor` will override the first one, so the final `InputDecorationSpec` will have the `fillColor` as `Colors.red`. + +## 3. Build the Custom Widget + +The custom widget is the widget that will use the `InputDecorationSpec` to build itself. It's a class that has a `SpecBuilder` in its composition. For this example, the `CustomTextField` is: + +```dart +class StyledTextField extends StyledWidget { + const StyledTextField({ + super.key, + super.style, + super.orderOfModifiers = const [], + }); + + @override + Widget build(BuildContext context) { + return SpecBuilder( + style: style, + orderOfModifiers: orderOfModifiers, + builder: (context) { + final inputDecoration = InputDecorationSpec.of(context); + + return TextField( + decoration: InputDecoration( + border: inputDecoration.border, + filled: inputDecoration.filled, + fillColor: inputDecoration.fillColor, + contentPadding: inputDecoration.contentPadding, + ), + ); + }, + ); + } +} +``` + +The `SpecBuilder` is a class that extends `StyledWidget`. The `build` method uses the `withMix` method to transform the style received from StyledTextField to a `MixData`, it also verifies if there are some inheritable attributes from the parent widgets, but this only happens if the `inherit` property is `true`. With the `MixData` instance in hands, you can use the `InputDecorationSpec.of` method to get the `InputDecorationSpec` from the `MixData`. Now you are able to apply the `InputDecorationSpec` to the `TextField` and return it. + +Now you are already ready to use the `StyledTextField` in your app and customize the `InputDecoration` of the `TextField` with Mix. + +```dart +final style = Style( + InputDecorationSpecAttribute( + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(20), + borderSide: BorderSide.none, + ), + fillColor: ColorDto(Colors.blueAccent.shade200), + filled: true, + contentPadding: SpacingDto.all(24), + ), +); +``` + +## 4. Create the Utility + +In the last step, we mentioned that you're ready to use the `StyledTextField` in your app, which is true. However, there's an opportunity to enhance its usability further. By creating a utility, you can simplify the process of applying attributes to the `InputDecoration`, making it even more convenient to customize your text fields. + +```dart +class InputDecorationUtility + extends SpecUtility { + InputDecorationUtility(super.builder); + + @override + T only({ + InputBorder? border, + bool? filled, + ColorDto? fillColor, + SpacingDto? contentPadding, + }) { + return builder( + InputDecorationSpecAttribute( + border: border, + filled: filled, + fillColor: fillColor, + contentPadding: contentPadding, + ), + ); + } + + late final fillColor = ColorUtility((color) => only(fillColor: color)); + + late final filled = BoolUtility((boolean) => only(filled: boolean)); + + late final contentPadding = + SpacingUtility((spacing) => only(contentPadding: spacing)); + + T border(InputBorder inputBorder) => only(border: inputBorder); +} + +``` + +The `InputDecorationUtility` is a class that extends `SpecUtility` and has methods to create the `InputDecorationSpecAttribute` with the attributes of the `InputDecoration`. The awesome thing about it is that each pre-defined Utility has some facilities to use the attributes. For example, the `filled` returns a `BoolUtility` that comes with `on` and `off` methods to make the code more readable, or the `fillColor` that returns a `ColorUtility` that comes with a bunch of methods to make it easier to use the `Color` attributes and perform operations with them. + +To finish, you can create a variable to use the `InputDecorationUtility`, like this: + +```dart +final $inputDecoration = InputDecorationUtility(MixUtility.selfBuilder); +``` + +So you can write the `Style` like this: + +```dart +final style = Style( + $inputDecoration.border( + OutlineInputBorder( + borderRadius: BorderRadius.circular(20), + borderSide: BorderSide.none, + ), + ), + $inputDecoration.filled.on(), + $inputDecoration.fillColor., + $inputDecoration.contentPadding.all(24), + $with.scale(2), +); +```