diff --git a/.fvmrc b/.fvmrc index c300356..227835d 100644 --- a/.fvmrc +++ b/.fvmrc @@ -1,3 +1,7 @@ { - "flutter": "stable" + "flutter": "stable", + "flavors": { + "stable": "stable", + "beta": "beta" + } } \ No newline at end of file diff --git a/.github/workflows/base.yaml b/.github/workflows/base.yaml index 7a5a9f5..ba06e7b 100644 --- a/.github/workflows/base.yaml +++ b/.github/workflows/base.yaml @@ -20,7 +20,7 @@ jobs: build: uses: flutter-form-builder-ecosystem/.github/.github/workflows/minimal-quality.yaml@main with: - codecov-name: 'form_builder_cupertino_fields' + codecov-name: form_builder_cupertino_fields example: uses: flutter-form-builder-ecosystem/.github/.github/workflows/build-examples.yaml@main diff --git a/example/.metadata b/example/.metadata index b02a7e4..d77a4e0 100644 --- a/example/.metadata +++ b/example/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled and should not be manually edited. version: - revision: "17025dd88227cd9532c33fa78f5250d548d87e9a" + revision: "c23637390482d4cf9598c3ce3f2be31aa7332daf" channel: "stable" project_type: app @@ -13,26 +13,26 @@ project_type: app migration: platforms: - platform: root - create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a - base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + create_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf + base_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf - platform: android - create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a - base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + create_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf + base_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf - platform: ios - create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a - base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + create_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf + base_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf - platform: linux - create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a - base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + create_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf + base_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf - platform: macos - create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a - base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + create_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf + base_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf - platform: web - create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a - base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + create_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf + base_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf - platform: windows - create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a - base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a + create_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf + base_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf # User provided section diff --git a/example/android/.gitignore b/example/android/.gitignore index 55afd91..be3943c 100644 --- a/example/android/.gitignore +++ b/example/android/.gitignore @@ -5,6 +5,7 @@ gradle-wrapper.jar /gradlew.bat /local.properties GeneratedPluginRegistrant.java +.cxx/ # Remember to never publicly share your keystore. # See https://flutter.dev/to/reference-keystore diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle.kts similarity index 57% rename from example/android/app/build.gradle rename to example/android/app/build.gradle.kts index b5511a9..c073f6b 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle.kts @@ -1,27 +1,26 @@ plugins { - id "com.android.application" - id "kotlin-android" + id("com.android.application") + id("kotlin-android") // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. - id "dev.flutter.flutter-gradle-plugin" + id("dev.flutter.flutter-gradle-plugin") } android { - namespace = "com.example.example" + namespace = "com.flutterformbuilderecosystem.example" compileSdk = flutter.compileSdkVersion ndkVersion = flutter.ndkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = JavaVersion.VERSION_1_8 + jvmTarget = JavaVersion.VERSION_11.toString() } defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId = "com.example.example" + applicationId = "com.flutterformbuilderecosystem.example" // You can update the following values to match your application needs. // For more information, see: https://flutter.dev/to/review-gradle-config. minSdk = flutter.minSdkVersion @@ -32,9 +31,8 @@ android { buildTypes { release { - // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig = signingConfigs.debug + signingConfig = signingConfigs.getByName("debug") } } } diff --git a/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt b/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt deleted file mode 100644 index 70f8f08..0000000 --- a/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.example.example - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() diff --git a/example/android/app/src/main/kotlin/com/flutterformbuilderecosystem/example/MainActivity.kt b/example/android/app/src/main/kotlin/com/flutterformbuilderecosystem/example/MainActivity.kt new file mode 100644 index 0000000..5395018 --- /dev/null +++ b/example/android/app/src/main/kotlin/com/flutterformbuilderecosystem/example/MainActivity.kt @@ -0,0 +1,5 @@ +package com.flutterformbuilderecosystem.example + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity : FlutterActivity() diff --git a/example/android/build.gradle b/example/android/build.gradle deleted file mode 100644 index d2ffbff..0000000 --- a/example/android/build.gradle +++ /dev/null @@ -1,18 +0,0 @@ -allprojects { - repositories { - google() - mavenCentral() - } -} - -rootProject.buildDir = "../build" -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(":app") -} - -tasks.register("clean", Delete) { - delete rootProject.buildDir -} diff --git a/example/android/build.gradle.kts b/example/android/build.gradle.kts new file mode 100644 index 0000000..89176ef --- /dev/null +++ b/example/android/build.gradle.kts @@ -0,0 +1,21 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get() +rootProject.layout.buildDirectory.value(newBuildDir) + +subprojects { + val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) + project.layout.buildDirectory.value(newSubprojectBuildDir) +} +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean") { + delete(rootProject.layout.buildDirectory) +} diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 2597170..f018a61 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -1,3 +1,3 @@ -org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true android.enableJetifier=true diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 7bb2df6..afa1e8e 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip diff --git a/example/android/settings.gradle b/example/android/settings.gradle deleted file mode 100644 index a42444d..0000000 --- a/example/android/settings.gradle +++ /dev/null @@ -1,25 +0,0 @@ -pluginManagement { - def flutterSdkPath = { - def properties = new Properties() - file("local.properties").withInputStream { properties.load(it) } - def flutterSdkPath = properties.getProperty("flutter.sdk") - assert flutterSdkPath != null, "flutter.sdk not set in local.properties" - return flutterSdkPath - }() - - includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") - - repositories { - google() - mavenCentral() - gradlePluginPortal() - } -} - -plugins { - id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "8.2.1" apply false - id "org.jetbrains.kotlin.android" version "1.8.22" apply false -} - -include ":app" diff --git a/example/android/settings.gradle.kts b/example/android/settings.gradle.kts new file mode 100644 index 0000000..a439442 --- /dev/null +++ b/example/android/settings.gradle.kts @@ -0,0 +1,25 @@ +pluginManagement { + val flutterSdkPath = run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + val flutterSdkPath = properties.getProperty("flutter.sdk") + require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } + flutterSdkPath + } + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id("dev.flutter.flutter-plugin-loader") version "1.0.0" + id("com.android.application") version "8.7.0" apply false + id("org.jetbrains.kotlin.android") version "1.8.22" apply false +} + +include(":app") diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index ce3bc8f..53556f4 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -368,7 +368,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; + PRODUCT_BUNDLE_IDENTIFIER = com.flutterformbuilderecosystem.example; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -384,7 +384,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.example.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.flutterformbuilderecosystem.example.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -401,7 +401,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.example.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.flutterformbuilderecosystem.example.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -416,7 +416,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.example.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.flutterformbuilderecosystem.example.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -547,7 +547,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; + PRODUCT_BUNDLE_IDENTIFIER = com.flutterformbuilderecosystem.example; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -569,7 +569,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; + PRODUCT_BUNDLE_IDENTIFIER = com.flutterformbuilderecosystem.example; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 8e3ca5d..15cada4 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -59,6 +59,7 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" + enableGPUValidationMode = "1" allowLocationSimulation = "YES"> diff --git a/example/lib/main.dart b/example/lib/main.dart index 171c6e1..cb2a56e 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -84,23 +84,26 @@ class _MyHomePageState extends State { autovalidateMode: AutovalidateMode.onUserInteraction, min: 1, max: 100, - validator: (value) => value != null && value < 50 && value > 5 - ? null - : 'Required value between 5 and 50', + validator: + (value) => + value != null && value < 50 && value > 5 + ? null + : 'Required value between 5 and 50', ), const SizedBox(height: 16), FormBuilderCupertinoTextField( name: 'text', decoration: BoxDecoration( - border: Border.all( - color: CupertinoColors.black, - ), + border: Border.all(color: CupertinoColors.black), borderRadius: BorderRadius.circular(8), ), autovalidateMode: AutovalidateMode.onUserInteraction, - validator: (value) => - value != null && value.length > 4 ? null : 'Write a text', - ) + validator: + (value) => + value != null && value.length > 4 + ? null + : 'Write a text', + ), ], ), ), diff --git a/example/linux/CMakeLists.txt b/example/linux/CMakeLists.txt index 74c66dd..2d3123c 100644 --- a/example/linux/CMakeLists.txt +++ b/example/linux/CMakeLists.txt @@ -1,5 +1,5 @@ # Project-level configuration. -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.13) project(runner LANGUAGES CXX) # The name of the executable created for the application. Change this to change @@ -7,7 +7,7 @@ project(runner LANGUAGES CXX) set(BINARY_NAME "example") # The unique GTK application identifier for this application. See: # https://wiki.gnome.org/HowDoI/ChooseApplicationID -set(APPLICATION_ID "com.example.example") +set(APPLICATION_ID "com.flutterformbuilderecosystem.example") # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. @@ -54,25 +54,8 @@ add_subdirectory(${FLUTTER_MANAGED_DIR}) 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) +# Application build; see runner/CMakeLists.txt. +add_subdirectory("runner") # Run the Flutter tool portions of the build. This must not be removed. add_dependencies(${BINARY_NAME} flutter_assemble) @@ -86,6 +69,7 @@ set_target_properties(${BINARY_NAME} 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) @@ -122,6 +106,12 @@ foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) COMPONENT Runtime) endforeach(bundled_library) +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + # 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") diff --git a/example/linux/main.cc b/example/linux/main.cc deleted file mode 100644 index e7c5c54..0000000 --- a/example/linux/main.cc +++ /dev/null @@ -1,6 +0,0 @@ -#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/example/linux/my_application.cc b/example/linux/my_application.cc deleted file mode 100644 index 0ba8f43..0000000 --- a/example/linux/my_application.cc +++ /dev/null @@ -1,104 +0,0 @@ -#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, "example"); - 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, "example"); - } - - 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/example/linux/my_application.h b/example/linux/my_application.h deleted file mode 100644 index 72271d5..0000000 --- a/example/linux/my_application.h +++ /dev/null @@ -1,18 +0,0 @@ -#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/example/macos/Runner.xcodeproj/project.pbxproj b/example/macos/Runner.xcodeproj/project.pbxproj index d9333e4..52415b1 100644 --- a/example/macos/Runner.xcodeproj/project.pbxproj +++ b/example/macos/Runner.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ /* 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 */; }; @@ -29,6 +30,13 @@ /* 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 */; @@ -52,6 +60,8 @@ /* 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 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -71,6 +81,13 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 331C80D2294CF70F00263BE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 33CC10EA2044A3C60003C045 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -81,6 +98,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 331C80D6294CF71000263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C80D7294CF71000263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; 33BA886A226E78AF003329D5 /* Configs */ = { isa = PBXGroup; children = ( @@ -97,6 +122,7 @@ children = ( 33FAB671232836740065AC1E /* Runner */, 33CEB47122A05771004F2AC0 /* Flutter */, + 331C80D6294CF71000263BE5 /* RunnerTests */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, ); @@ -106,6 +132,7 @@ isa = PBXGroup; children = ( 33CC10ED2044A3C60003C045 /* example.app */, + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, ); name = Products; sourceTree = ""; @@ -155,6 +182,24 @@ /* 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" */; @@ -181,10 +226,15 @@ 33CC10E52044A3C60003C045 /* Project object */ = { isa = PBXProject; attributes = { + BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { + 331C80D4294CF70F00263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 33CC10EC2044A3C60003C045; + }; 33CC10EC2044A3C60003C045 = { CreatedOnToolsVersion = 9.2; LastSwiftMigration = 1100; @@ -215,12 +265,20 @@ 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; @@ -274,6 +332,14 @@ /* 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; @@ -287,6 +353,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC10EC2044A3C60003C045 /* Runner */; + targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; + }; 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; @@ -307,11 +378,54 @@ /* 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.flutterformbuilderecosystem.example.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/example"; + }; + 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.flutterformbuilderecosystem.example.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/example"; + }; + 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.flutterformbuilderecosystem.example.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/example"; + }; + name = Profile; + }; 338D0CE9231458BD00FA5F75 /* Profile */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -335,9 +449,11 @@ CLANG_WARN_SUSPICIOUS_MOVE = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -385,6 +501,7 @@ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -408,9 +525,11 @@ CLANG_WARN_SUSPICIOUS_MOVE = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -438,6 +557,7 @@ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -461,9 +581,11 @@ CLANG_WARN_SUSPICIOUS_MOVE = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -537,6 +659,16 @@ /* 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 = ( diff --git a/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index fb7259e..ac78810 100644 --- a/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ + + + + diff --git a/example/macos/Runner/AppDelegate.swift b/example/macos/Runner/AppDelegate.swift index d53ef64..b3c1761 100644 --- a/example/macos/Runner/AppDelegate.swift +++ b/example/macos/Runner/AppDelegate.swift @@ -1,9 +1,13 @@ import Cocoa import FlutterMacOS -@NSApplicationMain +@main class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true } + + override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } } diff --git a/example/macos/Runner/Configs/AppInfo.xcconfig b/example/macos/Runner/Configs/AppInfo.xcconfig index dda192b..8f1e124 100644 --- a/example/macos/Runner/Configs/AppInfo.xcconfig +++ b/example/macos/Runner/Configs/AppInfo.xcconfig @@ -8,7 +8,7 @@ PRODUCT_NAME = example // The application's bundle identifier -PRODUCT_BUNDLE_IDENTIFIER = com.example.example +PRODUCT_BUNDLE_IDENTIFIER = com.flutterformbuilderecosystem.example // The copyright displayed in application information -PRODUCT_COPYRIGHT = Copyright © 2023 com.example. All rights reserved. +PRODUCT_COPYRIGHT = Copyright © 2025 com.flutterformbuilderecosystem. All rights reserved. diff --git a/example/macos/Runner/MainFlutterWindow.swift b/example/macos/Runner/MainFlutterWindow.swift index 2722837..3cc05eb 100644 --- a/example/macos/Runner/MainFlutterWindow.swift +++ b/example/macos/Runner/MainFlutterWindow.swift @@ -3,7 +3,7 @@ import FlutterMacOS class MainFlutterWindow: NSWindow { override func awakeFromNib() { - let flutterViewController = FlutterViewController.init() + let flutterViewController = FlutterViewController() let windowFrame = self.frame self.contentViewController = flutterViewController self.setFrame(windowFrame, display: true) diff --git a/example/pubspec.lock b/example/pubspec.lock index b9c82d0..a3ce752 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,42 +5,42 @@ packages: dependency: transitive description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.12.0" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" characters: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" clock: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection - sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.19.0" + version: "1.19.1" cupertino_icons: dependency: "direct main" description: @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" flutter: dependency: "direct main" description: flutter @@ -66,10 +66,10 @@ packages: dependency: "direct main" description: name: flutter_form_builder - sha256: "39aee5a2548df0b3979a83eea38468116a888341fbca8a92c4be18a486a7bb57" + sha256: aa3901466c70b69ae6c7f3d03fcbccaec5fde179d3fded0b10203144b546ad28 url: "https://pub.dev" source: hosted - version: "9.6.0" + version: "10.0.1" flutter_lints: dependency: "direct dev" description: @@ -102,18 +102,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" + sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec url: "https://pub.dev" source: hosted - version: "10.0.7" + version: "10.0.8" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" + sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 url: "https://pub.dev" source: hosted - version: "3.0.8" + version: "3.0.9" leak_tracker_testing: dependency: transitive description: @@ -134,10 +134,10 @@ packages: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.17" material_color_utilities: dependency: transitive description: @@ -150,18 +150,18 @@ packages: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.16.0" path: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" sky_engine: dependency: transitive description: flutter @@ -171,50 +171,50 @@ packages: dependency: transitive description: name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.10.1" stack_trace: dependency: transitive description: name: stack_trace - sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" string_scanner: dependency: transitive description: name: string_scanner - sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.1" term_glyph: dependency: transitive description: name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" test_api: dependency: transitive description: name: test_api - sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" + sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd url: "https://pub.dev" source: hosted - version: "0.7.3" + version: "0.7.4" vector_math: dependency: transitive description: @@ -227,10 +227,10 @@ packages: dependency: transitive description: name: vm_service - sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b + sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" url: "https://pub.dev" source: hosted - version: "14.3.0" + version: "14.3.1" sdks: - dart: ">=3.6.0 <4.0.0" - flutter: ">=3.27.0" + dart: ">=3.7.0 <4.0.0" + flutter: ">=3.29.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index fb3d8cd..4e40bb2 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -5,14 +5,14 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: '>=3.6.0 <4.0.0' - flutter: ">=3.27.0" + sdk: '>=3.7.0 <4.0.0' + flutter: ">=3.29.0" dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.8 - flutter_form_builder: ^9.6.0 + flutter_form_builder: ^10.0.1 form_builder_cupertino_fields: path: ../ diff --git a/example/windows/CMakeLists.txt b/example/windows/CMakeLists.txt index c027074..d960948 100644 --- a/example/windows/CMakeLists.txt +++ b/example/windows/CMakeLists.txt @@ -8,7 +8,7 @@ set(BINARY_NAME "example") # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. -cmake_policy(SET CMP0063 NEW) +cmake_policy(VERSION 3.14...3.25) # Define build configuration option. get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) @@ -52,6 +52,7 @@ 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) @@ -86,6 +87,12 @@ if(PLUGIN_BUNDLED_LIBRARIES) COMPONENT Runtime) endif() +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + # 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") diff --git a/example/windows/flutter/CMakeLists.txt b/example/windows/flutter/CMakeLists.txt index 930d207..903f489 100644 --- a/example/windows/flutter/CMakeLists.txt +++ b/example/windows/flutter/CMakeLists.txt @@ -10,6 +10,11 @@ include(${EPHEMERAL_DIR}/generated_config.cmake) # https://github.com/flutter/flutter/issues/57146. set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") +# Set fallback configurations for older versions of the flutter tool. +if (NOT DEFINED FLUTTER_TARGET_PLATFORM) + set(FLUTTER_TARGET_PLATFORM "windows-x64") +endif() + # === Flutter Library === set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") @@ -92,7 +97,7 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" - windows-x64 $ + ${FLUTTER_TARGET_PLATFORM} $ VERBATIM ) add_custom_target(flutter_assemble DEPENDS diff --git a/example/windows/runner/Runner.rc b/example/windows/runner/Runner.rc index aecaa2b..37a29fe 100644 --- a/example/windows/runner/Runner.rc +++ b/example/windows/runner/Runner.rc @@ -89,11 +89,11 @@ BEGIN BEGIN BLOCK "040904e4" BEGIN - VALUE "CompanyName", "com.example" "\0" + VALUE "CompanyName", "com.flutterformbuilderecosystem" "\0" VALUE "FileDescription", "example" "\0" VALUE "FileVersion", VERSION_AS_STRING "\0" VALUE "InternalName", "example" "\0" - VALUE "LegalCopyright", "Copyright (C) 2023 com.example. All rights reserved." "\0" + VALUE "LegalCopyright", "Copyright (C) 2025 com.flutterformbuilderecosystem. All rights reserved." "\0" VALUE "OriginalFilename", "example.exe" "\0" VALUE "ProductName", "example" "\0" VALUE "ProductVersion", VERSION_AS_STRING "\0" diff --git a/example/windows/runner/flutter_window.cpp b/example/windows/runner/flutter_window.cpp index b25e363..955ee30 100644 --- a/example/windows/runner/flutter_window.cpp +++ b/example/windows/runner/flutter_window.cpp @@ -31,6 +31,11 @@ bool FlutterWindow::OnCreate() { this->Show(); }); + // Flutter can complete the first frame before the "show window" callback is + // registered. The following call ensures a frame is pending to ensure the + // window is shown. It is a no-op if the first frame hasn't completed yet. + flutter_controller_->ForceRedraw(); + return true; } diff --git a/example/windows/runner/runner.exe.manifest b/example/windows/runner/runner.exe.manifest index a42ea76..153653e 100644 --- a/example/windows/runner/runner.exe.manifest +++ b/example/windows/runner/runner.exe.manifest @@ -9,12 +9,6 @@ - - - - - - diff --git a/example/windows/runner/utils.cpp b/example/windows/runner/utils.cpp index f5bf9fa..3a0b465 100644 --- a/example/windows/runner/utils.cpp +++ b/example/windows/runner/utils.cpp @@ -45,9 +45,11 @@ std::string Utf8FromUtf16(const wchar_t* utf16_string) { if (utf16_string == nullptr) { return std::string(); } - int target_length = ::WideCharToMultiByte( + unsigned int target_length = ::WideCharToMultiByte( CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - -1, nullptr, 0, nullptr, nullptr); + -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; @@ -55,8 +57,7 @@ std::string Utf8FromUtf16(const wchar_t* utf16_string) { utf8_string.resize(target_length); int converted_length = ::WideCharToMultiByte( CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - -1, utf8_string.data(), - target_length, nullptr, nullptr); + input_length, utf8_string.data(), target_length, nullptr, nullptr); if (converted_length == 0) { return std::string(); } diff --git a/example/windows/runner/win32_window.cpp b/example/windows/runner/win32_window.cpp index 041a385..60608d0 100644 --- a/example/windows/runner/win32_window.cpp +++ b/example/windows/runner/win32_window.cpp @@ -60,7 +60,7 @@ class WindowClassRegistrar { public: ~WindowClassRegistrar() = default; - // Returns the singleton registar instance. + // Returns the singleton registrar instance. static WindowClassRegistrar* GetInstance() { if (!instance_) { instance_ = new WindowClassRegistrar(); diff --git a/example/windows/runner/win32_window.h b/example/windows/runner/win32_window.h index c86632d..e901dde 100644 --- a/example/windows/runner/win32_window.h +++ b/example/windows/runner/win32_window.h @@ -77,7 +77,7 @@ class Win32Window { // 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 - // responsponds to changes in DPI. All other messages are handled by + // responds to changes in DPI. All other messages are handled by // MessageHandler. static LRESULT CALLBACK WndProc(HWND const window, UINT const message, diff --git a/lib/src/fields/form_builder_cupertino_checkbox.dart b/lib/src/fields/form_builder_cupertino_checkbox.dart index eab0ba4..851a44b 100644 --- a/lib/src/fields/form_builder_cupertino_checkbox.dart +++ b/lib/src/fields/form_builder_cupertino_checkbox.dart @@ -152,43 +152,46 @@ class FormBuilderCupertinoCheckbox extends FormBuilderField { this.autofocus = false, this.mouseCursor, }) : super( - builder: (FormFieldState field) { - final state = field as _FormBuilderCupertinoCheckboxState; - - final fieldWidget = CupertinoCheckbox( - focusColor: focusColor, - focusNode: state.effectiveFocusNode, - fillColor: fillColor, - value: state.value ?? false, - checkColor: checkColor, - shape: shape, - side: side, - tristate: tristate, - autofocus: autofocus, - mouseCursor: mouseCursor, - semanticLabel: semanticLabel, - onChanged: state.enabled - ? (value) { - field.didChange(value); - } - : null, - activeColor: activeColor, - ); - return CupertinoFormRow( - error: state.hasError - ? errorBuilder != null - ? errorBuilder(state.errorText ?? '') - : Text(state.errorText ?? '') - : null, - helper: helper, - padding: contentPadding, - prefix: prefix, - child: shouldExpandedField - ? SizedBox(width: double.infinity, child: fieldWidget) - : fieldWidget, - ); - }, - ); + builder: (FormFieldState field) { + final state = field as _FormBuilderCupertinoCheckboxState; + + final fieldWidget = CupertinoCheckbox( + focusColor: focusColor, + focusNode: state.effectiveFocusNode, + fillColor: fillColor, + value: state.value ?? false, + checkColor: checkColor, + shape: shape, + side: side, + tristate: tristate, + autofocus: autofocus, + mouseCursor: mouseCursor, + semanticLabel: semanticLabel, + onChanged: + state.enabled + ? (value) { + field.didChange(value); + } + : null, + activeColor: activeColor, + ); + return CupertinoFormRow( + error: + state.hasError + ? errorBuilder != null + ? errorBuilder(state.errorText ?? '') + : Text(state.errorText ?? '') + : null, + helper: helper, + padding: contentPadding, + prefix: prefix, + child: + shouldExpandedField + ? SizedBox(width: double.infinity, child: fieldWidget) + : fieldWidget, + ); + }, + ); @override FormBuilderFieldState createState() => diff --git a/lib/src/fields/form_builder_cupertino_segmented_control.dart b/lib/src/fields/form_builder_cupertino_segmented_control.dart index 0b9f08e..e60f9b6 100644 --- a/lib/src/fields/form_builder_cupertino_segmented_control.dart +++ b/lib/src/fields/form_builder_cupertino_segmented_control.dart @@ -99,45 +99,46 @@ class FormBuilderCupertinoSegmentedControl this.contentPadding, this.prefix, }) : super( - builder: (FormFieldState field) { - final state = - field as _FormBuilderCupertinoSegmentedControlState; - final theme = CupertinoTheme.of(state.context); - - final fieldWidget = CupertinoSegmentedControl( - borderColor: borderColor ?? theme.primaryColor, - selectedColor: selectedColor ?? theme.primaryColor, - pressedColor: pressedColor ?? theme.primaryColor, - groupValue: state.value, - children: { - for (final option in options) option.value: option, - }, - padding: padding, - unselectedColor: unselectedColor, - onValueChanged: (value) { - state.enabled ? field.didChange(value) : field.reset(); - }, - ); - - return CupertinoFormRow( - error: state.hasError - ? errorBuilder != null - ? errorBuilder(state.errorText ?? '') - : Text(state.errorText ?? '') - : null, - helper: helper, - padding: contentPadding, - prefix: prefix, - child: shouldExpandedField - ? SizedBox(width: double.infinity, child: fieldWidget) - : fieldWidget, - ); - }, - ); + builder: (FormFieldState field) { + final state = field as _FormBuilderCupertinoSegmentedControlState; + final theme = CupertinoTheme.of(state.context); + + final fieldWidget = CupertinoSegmentedControl( + borderColor: borderColor ?? theme.primaryColor, + selectedColor: selectedColor ?? theme.primaryColor, + pressedColor: pressedColor ?? theme.primaryColor, + groupValue: state.value, + children: { + for (final option in options) option.value: option, + }, + padding: padding, + unselectedColor: unselectedColor, + onValueChanged: (value) { + state.enabled ? field.didChange(value) : field.reset(); + }, + ); + + return CupertinoFormRow( + error: + state.hasError + ? errorBuilder != null + ? errorBuilder(state.errorText ?? '') + : Text(state.errorText ?? '') + : null, + helper: helper, + padding: contentPadding, + prefix: prefix, + child: + shouldExpandedField + ? SizedBox(width: double.infinity, child: fieldWidget) + : fieldWidget, + ); + }, + ); @override FormBuilderFieldState, T> - createState() => _FormBuilderCupertinoSegmentedControlState(); + createState() => _FormBuilderCupertinoSegmentedControlState(); } class _FormBuilderCupertinoSegmentedControlState diff --git a/lib/src/fields/form_builder_cupertino_slider.dart b/lib/src/fields/form_builder_cupertino_slider.dart index 03cc3a0..71908a2 100644 --- a/lib/src/fields/form_builder_cupertino_slider.dart +++ b/lib/src/fields/form_builder_cupertino_slider.dart @@ -187,67 +187,69 @@ class FormBuilderCupertinoSlider extends FormBuilderField { this.contentPadding, this.prefix, }) : super( - builder: (FormFieldState field) { - final state = field as _FormBuilderCupertinoSliderState; - final effectiveNumberFormat = - numberFormat ?? NumberFormat.compact(); + builder: (FormFieldState field) { + final state = field as _FormBuilderCupertinoSliderState; + final effectiveNumberFormat = numberFormat ?? NumberFormat.compact(); - final fieldWidget = Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - SizedBox( - width: double.infinity, - child: CupertinoSlider( - value: field.value!, - min: min, - max: max, - divisions: divisions, - activeColor: activeColor, - onChangeEnd: onChangeEnd, - onChangeStart: onChangeStart, - onChanged: state.enabled - ? (value) { - field.didChange(value); - } - : null, - thumbColor: thumbColor, - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - if (displayValues != DisplayValues.none && - displayValues != DisplayValues.current) - minValueWidget?.call(effectiveNumberFormat.format(min)) ?? - Text(effectiveNumberFormat.format(min)), - if (displayValues != DisplayValues.none && - displayValues != DisplayValues.minMax) - valueWidget?.call( - effectiveNumberFormat.format(field.value)) ?? - Text(effectiveNumberFormat.format(field.value)), - if (displayValues != DisplayValues.none && - displayValues != DisplayValues.current) - maxValueWidget?.call(effectiveNumberFormat.format(max)) ?? - Text(effectiveNumberFormat.format(max)), - ], - ), - ], - ); + final fieldWidget = Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + SizedBox( + width: double.infinity, + child: CupertinoSlider( + value: field.value!, + min: min, + max: max, + divisions: divisions, + activeColor: activeColor, + onChangeEnd: onChangeEnd, + onChangeStart: onChangeStart, + onChanged: + state.enabled + ? (value) { + field.didChange(value); + } + : null, + thumbColor: thumbColor, + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (displayValues != DisplayValues.none && + displayValues != DisplayValues.current) + minValueWidget?.call(effectiveNumberFormat.format(min)) ?? + Text(effectiveNumberFormat.format(min)), + if (displayValues != DisplayValues.none && + displayValues != DisplayValues.minMax) + valueWidget?.call( + effectiveNumberFormat.format(field.value), + ) ?? + Text(effectiveNumberFormat.format(field.value)), + if (displayValues != DisplayValues.none && + displayValues != DisplayValues.current) + maxValueWidget?.call(effectiveNumberFormat.format(max)) ?? + Text(effectiveNumberFormat.format(max)), + ], + ), + ], + ); - return CupertinoFormRow( - error: state.hasError - ? errorBuilder != null - ? errorBuilder(state.errorText ?? '') - : Text(state.errorText ?? '') - : null, - helper: helper, - padding: contentPadding, - prefix: prefix, - child: fieldWidget, - ); - }, - ); + return CupertinoFormRow( + error: + state.hasError + ? errorBuilder != null + ? errorBuilder(state.errorText ?? '') + : Text(state.errorText ?? '') + : null, + helper: helper, + padding: contentPadding, + prefix: prefix, + child: fieldWidget, + ); + }, + ); @override FormBuilderFieldState createState() => diff --git a/lib/src/fields/form_builder_cupertino_sliding_segmented_control.dart b/lib/src/fields/form_builder_cupertino_sliding_segmented_control.dart index 8be68a3..8d53f8c 100644 --- a/lib/src/fields/form_builder_cupertino_sliding_segmented_control.dart +++ b/lib/src/fields/form_builder_cupertino_sliding_segmented_control.dart @@ -86,47 +86,53 @@ class FormBuilderCupertinoSlidingSegmentedControl this.contentPadding, this.prefix, }) : super( - builder: (FormFieldState field) { - final state = - field as _FormBuilderCupertinoSlidingSegmentedControlState; - final theme = CupertinoTheme.of(state.context); + builder: (FormFieldState field) { + final state = + field as _FormBuilderCupertinoSlidingSegmentedControlState; + final theme = CupertinoTheme.of(state.context); - final fieldWidget = CupertinoSlidingSegmentedControl( - backgroundColor: - backgroundColor ?? CupertinoColors.tertiarySystemFill, - thumbColor: thumbColor ?? theme.primaryColor, - groupValue: state.value, - children: { - for (final option in options) option.value: option, - }, - padding: padding ?? - const EdgeInsets.symmetric(vertical: 2, horizontal: 3), - onValueChanged: (value) { - state.enabled ? field.didChange(value) : field.reset(); - }, - ); + final fieldWidget = CupertinoSlidingSegmentedControl( + backgroundColor: + backgroundColor ?? CupertinoColors.tertiarySystemFill, + thumbColor: thumbColor ?? theme.primaryColor, + groupValue: state.value, + children: { + for (final option in options) option.value: option, + }, + padding: + padding ?? + const EdgeInsets.symmetric(vertical: 2, horizontal: 3), + onValueChanged: (value) { + state.enabled ? field.didChange(value) : field.reset(); + }, + ); - return CupertinoFormRow( - error: state.hasError - ? errorBuilder != null - ? errorBuilder(state.errorText ?? '') - : Text(state.errorText ?? '') - : null, - helper: helper, - padding: contentPadding, - prefix: prefix, - child: shouldExpandedField - ? SizedBox(width: double.infinity, child: fieldWidget) - : fieldWidget, - ); - }, - ); + return CupertinoFormRow( + error: + state.hasError + ? errorBuilder != null + ? errorBuilder(state.errorText ?? '') + : Text(state.errorText ?? '') + : null, + helper: helper, + padding: contentPadding, + prefix: prefix, + child: + shouldExpandedField + ? SizedBox(width: double.infinity, child: fieldWidget) + : fieldWidget, + ); + }, + ); @override FormBuilderFieldState, T> - createState() => _FormBuilderCupertinoSlidingSegmentedControlState(); + createState() => _FormBuilderCupertinoSlidingSegmentedControlState(); } class _FormBuilderCupertinoSlidingSegmentedControlState - extends FormBuilderFieldState< - FormBuilderCupertinoSlidingSegmentedControl, T> {} + extends + FormBuilderFieldState< + FormBuilderCupertinoSlidingSegmentedControl, + T + > {} diff --git a/lib/src/fields/form_builder_cupertino_switch.dart b/lib/src/fields/form_builder_cupertino_switch.dart index f5b0ecc..e327a04 100644 --- a/lib/src/fields/form_builder_cupertino_switch.dart +++ b/lib/src/fields/form_builder_cupertino_switch.dart @@ -336,52 +336,55 @@ class FormBuilderCupertinoSwitch extends FormBuilderField { this.trackOutlineWidth, this.thumbIcon, }) : super( - builder: (FormFieldState field) { - final state = field as _FormBuilderCupertinoSwitchState; + builder: (FormFieldState field) { + final state = field as _FormBuilderCupertinoSwitchState; - final fieldWidget = CupertinoSwitch( - value: state.value ?? false, - onChanged: state.enabled - ? (value) { - field.didChange(value); - } - : null, - dragStartBehavior: dragStartBehavior, - thumbColor: thumbColor, - activeTrackColor: activeTrackColor, - activeThumbImage: activeThumbImage, - inactiveThumbImage: inactiveThumbImage, - applyTheme: applyTheme, - autofocus: autofocus, - focusColor: focusColor, - focusNode: focusNode, - inactiveThumbColor: inactiveThumbColor, - inactiveTrackColor: inactiveTrackColor, - mouseCursor: mouseCursor, - onActiveThumbImageError: onActiveThumbImageError, - onInactiveThumbImageError: onInactiveThumbImageError, - offLabelColor: offLabelColor, - onLabelColor: onLabelColor, - onFocusChange: onFocusChange, - thumbIcon: thumbIcon, - trackOutlineColor: trackOutlineColor, - trackOutlineWidth: trackOutlineWidth, - ); - return CupertinoFormRow( - error: state.hasError - ? errorBuilder != null - ? errorBuilder(state.errorText ?? '') - : Text(state.errorText ?? '') - : null, - helper: helper, - padding: contentPadding, - prefix: prefix, - child: shouldExpandedField - ? SizedBox(width: double.infinity, child: fieldWidget) - : fieldWidget, - ); - }, - ); + final fieldWidget = CupertinoSwitch( + value: state.value ?? false, + onChanged: + state.enabled + ? (value) { + field.didChange(value); + } + : null, + dragStartBehavior: dragStartBehavior, + thumbColor: thumbColor, + activeTrackColor: activeTrackColor, + activeThumbImage: activeThumbImage, + inactiveThumbImage: inactiveThumbImage, + applyTheme: applyTheme, + autofocus: autofocus, + focusColor: focusColor, + focusNode: focusNode, + inactiveThumbColor: inactiveThumbColor, + inactiveTrackColor: inactiveTrackColor, + mouseCursor: mouseCursor, + onActiveThumbImageError: onActiveThumbImageError, + onInactiveThumbImageError: onInactiveThumbImageError, + offLabelColor: offLabelColor, + onLabelColor: onLabelColor, + onFocusChange: onFocusChange, + thumbIcon: thumbIcon, + trackOutlineColor: trackOutlineColor, + trackOutlineWidth: trackOutlineWidth, + ); + return CupertinoFormRow( + error: + state.hasError + ? errorBuilder != null + ? errorBuilder(state.errorText ?? '') + : Text(state.errorText ?? '') + : null, + helper: helper, + padding: contentPadding, + prefix: prefix, + child: + shouldExpandedField + ? SizedBox(width: double.infinity, child: fieldWidget) + : fieldWidget, + ); + }, + ); @override FormBuilderFieldState createState() => diff --git a/lib/src/fields/form_builder_cupertino_text_field.dart b/lib/src/fields/form_builder_cupertino_text_field.dart index 98a0728..c8600a5 100644 --- a/lib/src/fields/form_builder_cupertino_text_field.dart +++ b/lib/src/fields/form_builder_cupertino_text_field.dart @@ -284,6 +284,9 @@ class FormBuilderCupertinoTextField extends FormBuilderField { /// {@macro flutter.widgets.editableText.scribbleEnabled} final bool scribbleEnabled; + /// {@macro flutter.widgets.editableText.stylusHandwritingEnabled} + final bool stylusHandwritingEnabled; + /// {@macro flutter.services.TextInputConfiguration.enableIMEPersonalizedLearning} final bool enableIMEPersonalizedLearning; @@ -300,6 +303,29 @@ class FormBuilderCupertinoTextField extends FormBuilderField { /// {@macro flutter.widgets.editableText.contentInsertionConfiguration} final ContentInsertionConfiguration? contentInsertionConfiguration; + /// {@macro flutter.widgets.undoHistory.controller} + final UndoHistoryController? undoController; + + /// {@macro flutter.widgets.editableText.selectionControls} + final TextSelectionControls? selectionControls; + + /// {@macro flutter.widgets.editableText.groupId} + final Object groupId; + + /// {@macro flutter.widgets.EditableText.spellCheckConfiguration} + /// + /// If [SpellCheckConfiguration.misspelledTextStyle] is not specified in this + /// configuration, then [cupertinoMisspelledTextStyle] is used by default. + final SpellCheckConfiguration? spellCheckConfiguration; + + /// {@macro flutter.material.Material.clipBehavior} + /// + /// Defaults to [Clip.hardEdge]. + final Clip clipBehavior; + + /// {@macro flutter.widgets.editableText.cursorOpacityAnimates} + final bool cursorOpacityAnimates; + FormBuilderCupertinoTextField({ super.key, required super.name, @@ -363,107 +389,129 @@ class FormBuilderCupertinoTextField extends FormBuilderField { this.contentPadding, this.prefix, this.enableIMEPersonalizedLearning = true, + this.undoController, + this.selectionControls, + this.groupId = EditableText, + this.spellCheckConfiguration, + this.clipBehavior = Clip.hardEdge, + this.cursorOpacityAnimates = true, + @Deprecated( + 'Use `stylusHandwritingEnabled` instead. ' + 'This feature was deprecated after v3.27.0-0.2.pre.', + ) this.scribbleEnabled = true, + this.stylusHandwritingEnabled = + EditableText.defaultStylusHandwritingEnabled, this.clearButtonMode = OverlayVisibilityMode.never, this.contentInsertionConfiguration, this.placeholder, this.placeholderStyle, - }) : assert(maxLines == null || maxLines > 0), - assert(minLines == null || minLines > 0), - assert( - (maxLines == null) || (minLines == null) || (maxLines >= minLines), - "minLines can't be greater than maxLines", - ), - assert( - !expands || (maxLines == null && minLines == null), - 'minLines and maxLines must be null when expands is true.', - ), - assert(!obscureText || maxLines == 1, - 'Obscured fields cannot be multiline.'), - assert(maxLength == null || maxLength > 0), - // Assert the following instead of setting it directly to avoid surprising the user by silently changing the value they set. - assert( - !identical(textInputAction, TextInputAction.newline) || - maxLines == 1 || - !identical(keyboardType, TextInputType.text), - 'Use keyboardType TextInputType.multiline when using TextInputAction.newline on a multiline TextField.', - ), - super( - initialValue: controller != null ? controller.text : initialValue, - builder: (FormFieldState field) { - final state = field as _FormBuilderCupertinoTextFieldState; - - final fieldWidget = CupertinoTextField( - restorationId: restorationId, - controller: state._effectiveController, - focusNode: state.effectiveFocusNode, - decoration: decoration, - keyboardType: keyboardType, - textInputAction: textInputAction, - style: style, - strutStyle: strutStyle, - textAlign: textAlign, - textAlignVertical: textAlignVertical, - textDirection: textDirection, - textCapitalization: textCapitalization, - autofocus: autofocus, - readOnly: readOnly, - showCursor: showCursor, - obscureText: obscureText, - autocorrect: autocorrect, - enableSuggestions: enableSuggestions, - placeholder: placeholder, - placeholderStyle: placeholderStyle, - maxLengthEnforcement: maxLengthEnforcement, - maxLines: maxLines, - minLines: minLines, - expands: expands, - maxLength: maxLength, - onTap: onTap, - onTapOutside: onTapOutside, - onEditingComplete: onEditingComplete, - onSubmitted: onSubmitted, - inputFormatters: inputFormatters, - enabled: state.enabled, - cursorWidth: cursorWidth, - cursorHeight: cursorHeight, - cursorRadius: cursorRadius, - cursorColor: cursorColor, - scrollPadding: scrollPadding, - keyboardAppearance: keyboardAppearance, - enableInteractiveSelection: enableInteractiveSelection, - dragStartBehavior: dragStartBehavior, - scrollController: scrollController, - scrollPhysics: scrollPhysics, - selectionHeightStyle: selectionHeightStyle, - selectionWidthStyle: selectionWidthStyle, - smartDashesType: smartDashesType, - smartQuotesType: smartQuotesType, - contextMenuBuilder: contextMenuBuilder, - obscuringCharacter: obscuringCharacter, - autofillHints: autofillHints, - magnifierConfiguration: magnifierConfiguration, - enableIMEPersonalizedLearning: enableIMEPersonalizedLearning, - scribbleEnabled: scribbleEnabled, - clearButtonMode: clearButtonMode, - contentInsertionConfiguration: contentInsertionConfiguration, - ); - - return CupertinoFormRow( - error: state.hasError - ? errorBuilder != null - ? errorBuilder(state.errorText ?? '') - : Text(state.errorText ?? '') - : null, - helper: helper, - padding: contentPadding, - prefix: prefix, - child: shouldExpandedField - ? SizedBox(width: double.infinity, child: fieldWidget) - : fieldWidget, - ); - }, - ); + }) : assert(maxLines == null || maxLines > 0), + assert(minLines == null || minLines > 0), + assert( + (maxLines == null) || (minLines == null) || (maxLines >= minLines), + "minLines can't be greater than maxLines", + ), + assert( + !expands || (maxLines == null && minLines == null), + 'minLines and maxLines must be null when expands is true.', + ), + assert( + !obscureText || maxLines == 1, + 'Obscured fields cannot be multiline.', + ), + assert(maxLength == null || maxLength > 0), + // Assert the following instead of setting it directly to avoid surprising the user by silently changing the value they set. + assert( + !identical(textInputAction, TextInputAction.newline) || + maxLines == 1 || + !identical(keyboardType, TextInputType.text), + 'Use keyboardType TextInputType.multiline when using TextInputAction.newline on a multiline TextField.', + ), + super( + initialValue: controller != null ? controller.text : initialValue, + builder: (FormFieldState field) { + final state = field as _FormBuilderCupertinoTextFieldState; + + final fieldWidget = CupertinoTextField( + restorationId: restorationId, + controller: state._effectiveController, + focusNode: state.effectiveFocusNode, + decoration: decoration, + keyboardType: keyboardType, + textInputAction: textInputAction, + style: style, + strutStyle: strutStyle, + textAlign: textAlign, + textAlignVertical: textAlignVertical, + textDirection: textDirection, + textCapitalization: textCapitalization, + autofocus: autofocus, + readOnly: readOnly, + showCursor: showCursor, + obscureText: obscureText, + autocorrect: autocorrect, + enableSuggestions: enableSuggestions, + placeholder: placeholder, + placeholderStyle: placeholderStyle, + maxLengthEnforcement: maxLengthEnforcement, + maxLines: maxLines, + minLines: minLines, + expands: expands, + maxLength: maxLength, + onTap: onTap, + onTapOutside: onTapOutside, + onEditingComplete: onEditingComplete, + onSubmitted: onSubmitted, + inputFormatters: inputFormatters, + enabled: state.enabled, + cursorWidth: cursorWidth, + cursorHeight: cursorHeight, + cursorRadius: cursorRadius, + cursorColor: cursorColor, + scrollPadding: scrollPadding, + keyboardAppearance: keyboardAppearance, + enableInteractiveSelection: enableInteractiveSelection, + dragStartBehavior: dragStartBehavior, + scrollController: scrollController, + scrollPhysics: scrollPhysics, + selectionHeightStyle: selectionHeightStyle, + selectionWidthStyle: selectionWidthStyle, + smartDashesType: smartDashesType, + smartQuotesType: smartQuotesType, + contextMenuBuilder: contextMenuBuilder, + obscuringCharacter: obscuringCharacter, + autofillHints: autofillHints, + magnifierConfiguration: magnifierConfiguration, + enableIMEPersonalizedLearning: enableIMEPersonalizedLearning, + stylusHandwritingEnabled: stylusHandwritingEnabled, + undoController: undoController, + selectionControls: selectionControls, + groupId: groupId, + spellCheckConfiguration: spellCheckConfiguration, + clipBehavior: clipBehavior, + cursorOpacityAnimates: cursorOpacityAnimates, + clearButtonMode: clearButtonMode, + contentInsertionConfiguration: contentInsertionConfiguration, + ); + + return CupertinoFormRow( + error: + state.hasError + ? errorBuilder != null + ? errorBuilder(state.errorText ?? '') + : Text(state.errorText ?? '') + : null, + helper: helper, + padding: contentPadding, + prefix: prefix, + child: + shouldExpandedField + ? SizedBox(width: double.infinity, child: fieldWidget) + : fieldWidget, + ); + }, + ); static Widget _defaultContextMenuBuilder( BuildContext context, diff --git a/pubspec.yaml b/pubspec.yaml index b5499ea..a035605 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -6,20 +6,21 @@ issue_tracker: https://github.com/flutter-form-builder-ecosystem/form_builder_cu homepage: https://github.com/flutter-form-builder-ecosystem topics: - form - - forms - cupertino funding: - https://opencollective.com/flutter-form-builder-ecosystem environment: - sdk: '>=3.6.0 <4.0.0' - flutter: ">=3.27.0" + sdk: '>=3.7.0 <4.0.0' + flutter: ">=3.29.0" dependencies: flutter: sdk: flutter - flutter_form_builder: ^9.6.0 - intl: ^0.19.0 + flutter_form_builder: ^10.0.1 + # This version would be max, the same version used on flutter_localizations + # https://github.com/flutter/flutter/blob/17025dd88227cd9532c33fa78f5250d548d87e9a/packages/flutter_localizations/pubspec.yaml#L14 + intl: ">=0.19.0 <0.21.0" dev_dependencies: flutter_test: diff --git a/test/src/fields/form_builder_cupertino_checkbox_test.dart b/test/src/fields/form_builder_cupertino_checkbox_test.dart index 635b10f..e369b8f 100644 --- a/test/src/fields/form_builder_cupertino_checkbox_test.dart +++ b/test/src/fields/form_builder_cupertino_checkbox_test.dart @@ -6,8 +6,9 @@ import '../form_builder_tester.dart'; void main() { group('initialValue -', () { - testWidgets('should initial value when set initialValue', - (WidgetTester tester) async { + testWidgets('should initial value when set initialValue', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; final switchKey = GlobalKey(); final testWidget = FormBuilderCupertinoCheckbox( @@ -22,8 +23,9 @@ void main() { }); group('errors -', () { - testWidgets('should error text when value is false', - (WidgetTester tester) async { + testWidgets('should error text when value is false', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; const errorTextField = 'error text field'; final switchKey = GlobalKey(); @@ -47,8 +49,9 @@ void main() { expect(find.text(errorTextField), findsNothing); }); - testWidgets('should custom error text when invalidate field', - (WidgetTester tester) async { + testWidgets('should custom error text when invalidate field', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; const errorTextField = 'error text field'; final switchKey = GlobalKey(); @@ -63,8 +66,9 @@ void main() { expect(find.text(errorTextField), findsOneWidget); }); - testWidgets('should not show error text when value is true', - (WidgetTester tester) async { + testWidgets('should not show error text when value is true', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; final switchKey = GlobalKey(); const errorTextField = 'error text field'; @@ -119,24 +123,25 @@ void main() { expect(switchKey.currentState?.value, equals(initialValue)); }); testWidgets( - 'Should reset custom error when invalidate field and then reset', - (tester) async { - const widgetName = 'sc1'; - final switchKey = GlobalKey(); - const errorTextField = 'error text field'; - final testWidget = FormBuilderCupertinoCheckbox( - name: widgetName, - key: switchKey, - ); - await tester.pumpWidget(buildTestableFieldWidget(testWidget)); - - switchKey.currentState?.invalidate(errorTextField); - await tester.pumpAndSettle(); - - // Reset custom error - switchKey.currentState?.reset(); - await tester.pumpAndSettle(); - expect(find.text(errorTextField), findsNothing); - }); + 'Should reset custom error when invalidate field and then reset', + (tester) async { + const widgetName = 'sc1'; + final switchKey = GlobalKey(); + const errorTextField = 'error text field'; + final testWidget = FormBuilderCupertinoCheckbox( + name: widgetName, + key: switchKey, + ); + await tester.pumpWidget(buildTestableFieldWidget(testWidget)); + + switchKey.currentState?.invalidate(errorTextField); + await tester.pumpAndSettle(); + + // Reset custom error + switchKey.currentState?.reset(); + await tester.pumpAndSettle(); + expect(find.text(errorTextField), findsNothing); + }, + ); }); } diff --git a/test/src/fields/form_builder_cupertino_segmented_control_test.dart b/test/src/fields/form_builder_cupertino_segmented_control_test.dart index 8896a73..83368be 100644 --- a/test/src/fields/form_builder_cupertino_segmented_control_test.dart +++ b/test/src/fields/form_builder_cupertino_segmented_control_test.dart @@ -6,8 +6,9 @@ import '../form_builder_tester.dart'; void main() { group('initialValue -', () { - testWidgets('should initial value when set initialValue', - (WidgetTester tester) async { + testWidgets('should initial value when set initialValue', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; final textFieldKey = GlobalKey(); final testWidget = FormBuilderCupertinoSegmentedControl( @@ -26,8 +27,9 @@ void main() { }); group('errors -', () { - testWidgets('should error text when value is empty', - (WidgetTester tester) async { + testWidgets('should error text when value is empty', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; const errorTextField = 'error text field'; final textFieldKey = GlobalKey(); @@ -38,8 +40,8 @@ void main() { FormBuilderFieldOption(value: 'AM'), FormBuilderFieldOption(value: 'PM'), ], - validator: (value) => - value == null || value.isEmpty ? errorTextField : null, + validator: + (value) => value == null || value.isEmpty ? errorTextField : null, ); await tester.pumpWidget(buildTestableFieldWidget(testWidget)); @@ -56,8 +58,9 @@ void main() { expect(find.text(errorTextField), findsNothing); }); - testWidgets('should custom error text when invalidate field', - (WidgetTester tester) async { + testWidgets('should custom error text when invalidate field', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; const errorTextField = 'error text field'; final textFieldKey = GlobalKey(); @@ -76,8 +79,9 @@ void main() { expect(find.text(errorTextField), findsOneWidget); }); - testWidgets('should not show error text when some option is selected', - (WidgetTester tester) async { + testWidgets('should not show error text when some option is selected', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; final textFieldKey = GlobalKey(); const errorTextField = 'error text field'; @@ -88,8 +92,8 @@ void main() { FormBuilderFieldOption(value: 'AM'), FormBuilderFieldOption(value: 'PM'), ], - validator: (value) => - value == null || value.isEmpty ? errorTextField : null, + validator: + (value) => value == null || value.isEmpty ? errorTextField : null, ); await tester.pumpWidget(buildTestableFieldWidget(testWidget)); @@ -145,28 +149,29 @@ void main() { expect(textFieldKey.currentState?.value, equals(initialValue)); }); testWidgets( - 'Should reset custom error when invalidate field and then reset', - (tester) async { - const widgetName = 'sc1'; - final textFieldKey = GlobalKey(); - const errorTextField = 'error text field'; - final testWidget = FormBuilderCupertinoSegmentedControl( - name: widgetName, - key: textFieldKey, - options: const [ - FormBuilderFieldOption(value: 'AM'), - FormBuilderFieldOption(value: 'PM'), - ], - ); - await tester.pumpWidget(buildTestableFieldWidget(testWidget)); - - textFieldKey.currentState?.invalidate(errorTextField); - await tester.pumpAndSettle(); - - // Reset custom error - textFieldKey.currentState?.reset(); - await tester.pumpAndSettle(); - expect(find.text(errorTextField), findsNothing); - }); + 'Should reset custom error when invalidate field and then reset', + (tester) async { + const widgetName = 'sc1'; + final textFieldKey = GlobalKey(); + const errorTextField = 'error text field'; + final testWidget = FormBuilderCupertinoSegmentedControl( + name: widgetName, + key: textFieldKey, + options: const [ + FormBuilderFieldOption(value: 'AM'), + FormBuilderFieldOption(value: 'PM'), + ], + ); + await tester.pumpWidget(buildTestableFieldWidget(testWidget)); + + textFieldKey.currentState?.invalidate(errorTextField); + await tester.pumpAndSettle(); + + // Reset custom error + textFieldKey.currentState?.reset(); + await tester.pumpAndSettle(); + expect(find.text(errorTextField), findsNothing); + }, + ); }); } diff --git a/test/src/fields/form_builder_cupertino_slider_test.dart b/test/src/fields/form_builder_cupertino_slider_test.dart index 53f8e0a..15377fb 100644 --- a/test/src/fields/form_builder_cupertino_slider_test.dart +++ b/test/src/fields/form_builder_cupertino_slider_test.dart @@ -11,15 +11,20 @@ void main() { const double unit = CupertinoThumbPainter.radius; const double delta = 3.0 * unit; return tester.dragFrom( - topLeft + const Offset(unit, unit), const Offset(delta, 0.0)); + topLeft + const Offset(unit, unit), + const Offset(delta, 0.0), + ); } group('initialValue -', () { - testWidgets('should initial value when set initialValue', - (WidgetTester tester) async { + testWidgets('should initial value when set initialValue', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; - final switchKey = GlobalKey< - FormBuilderFieldState>(); + final switchKey = + GlobalKey< + FormBuilderFieldState + >(); final testWidget = FormBuilderCupertinoSlider( name: widgetName, max: 100, @@ -34,20 +39,23 @@ void main() { }); group('errors -', () { - testWidgets('should error text when value is bigger than 0', - (WidgetTester tester) async { + testWidgets('should error text when value is bigger than 0', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; const errorTextField = 'error text field'; - final switchKey = GlobalKey< - FormBuilderFieldState>(); + final switchKey = + GlobalKey< + FormBuilderFieldState + >(); final testWidget = FormBuilderCupertinoSlider( name: widgetName, key: switchKey, max: 10, min: 0, initialValue: 0, - validator: (value) => - value == null || value <= 0 ? errorTextField : null, + validator: + (value) => value == null || value <= 0 ? errorTextField : null, ); await tester.pumpWidget(buildTestableFieldWidget(testWidget)); @@ -64,12 +72,15 @@ void main() { expect(find.text(errorTextField), findsNothing); }); - testWidgets('should custom error text when invalidate field', - (WidgetTester tester) async { + testWidgets('should custom error text when invalidate field', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; const errorTextField = 'error text field'; - final switchKey = GlobalKey< - FormBuilderFieldState>(); + final switchKey = + GlobalKey< + FormBuilderFieldState + >(); final testWidget = FormBuilderCupertinoSlider( name: widgetName, key: switchKey, @@ -84,11 +95,14 @@ void main() { expect(find.text(errorTextField), findsOneWidget); }); - testWidgets('should not show error text when value is bigger than 0', - (WidgetTester tester) async { + testWidgets('should not show error text when value is bigger than 0', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; - final switchKey = GlobalKey< - FormBuilderFieldState>(); + final switchKey = + GlobalKey< + FormBuilderFieldState + >(); const errorTextField = 'error text field'; final testWidget = FormBuilderCupertinoSlider( name: widgetName, @@ -96,8 +110,8 @@ void main() { max: 10, min: 0, initialValue: 0, - validator: (value) => - value == null || value <= 0 ? errorTextField : null, + validator: + (value) => value == null || value <= 0 ? errorTextField : null, ); await tester.pumpWidget(buildTestableFieldWidget(testWidget)); @@ -114,8 +128,10 @@ void main() { group('reset -', () { testWidgets('Should reset to null when call reset', (tester) async { const widgetName = 'sc1'; - final switchKey = GlobalKey< - FormBuilderFieldState>(); + final switchKey = + GlobalKey< + FormBuilderFieldState + >(); final testWidget = FormBuilderCupertinoSlider( name: widgetName, key: switchKey, @@ -133,8 +149,10 @@ void main() { }); testWidgets('Should reset to initial when call reset', (tester) async { const widgetName = 'sc1'; - final switchKey = GlobalKey< - FormBuilderFieldState>(); + final switchKey = + GlobalKey< + FormBuilderFieldState + >(); const double initialValue = 0; final testWidget = FormBuilderCupertinoSlider( name: widgetName, @@ -152,28 +170,31 @@ void main() { expect(switchKey.currentState?.value, equals(initialValue)); }); testWidgets( - 'Should reset custom error when invalidate field and then reset', - (tester) async { - const widgetName = 'sc1'; - final switchKey = GlobalKey< - FormBuilderFieldState>(); - const errorTextField = 'error text field'; - final testWidget = FormBuilderCupertinoSlider( - name: widgetName, - key: switchKey, - max: 10, - min: 0, - initialValue: 0, - ); - await tester.pumpWidget(buildTestableFieldWidget(testWidget)); - - switchKey.currentState?.invalidate(errorTextField); - await tester.pumpAndSettle(); - - // Reset custom error - switchKey.currentState?.reset(); - await tester.pumpAndSettle(); - expect(find.text(errorTextField), findsNothing); - }); + 'Should reset custom error when invalidate field and then reset', + (tester) async { + const widgetName = 'sc1'; + final switchKey = + GlobalKey< + FormBuilderFieldState + >(); + const errorTextField = 'error text field'; + final testWidget = FormBuilderCupertinoSlider( + name: widgetName, + key: switchKey, + max: 10, + min: 0, + initialValue: 0, + ); + await tester.pumpWidget(buildTestableFieldWidget(testWidget)); + + switchKey.currentState?.invalidate(errorTextField); + await tester.pumpAndSettle(); + + // Reset custom error + switchKey.currentState?.reset(); + await tester.pumpAndSettle(); + expect(find.text(errorTextField), findsNothing); + }, + ); }); } diff --git a/test/src/fields/form_builder_cupertino_sliding_segmented_control_test.dart b/test/src/fields/form_builder_cupertino_sliding_segmented_control_test.dart index 2e27b39..544cf39 100644 --- a/test/src/fields/form_builder_cupertino_sliding_segmented_control_test.dart +++ b/test/src/fields/form_builder_cupertino_sliding_segmented_control_test.dart @@ -6,8 +6,9 @@ import '../form_builder_tester.dart'; void main() { group('initialValue -', () { - testWidgets('should initial value when set initialValue', - (WidgetTester tester) async { + testWidgets('should initial value when set initialValue', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; final textFieldKey = GlobalKey(); final testWidget = FormBuilderCupertinoSlidingSegmentedControl( @@ -26,8 +27,9 @@ void main() { }); group('errors -', () { - testWidgets('should error text when value is empty', - (WidgetTester tester) async { + testWidgets('should error text when value is empty', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; const errorTextField = 'error text field'; final textFieldKey = GlobalKey(); @@ -38,8 +40,8 @@ void main() { FormBuilderFieldOption(value: 'AM'), FormBuilderFieldOption(value: 'PM'), ], - validator: (value) => - value == null || value.isEmpty ? errorTextField : null, + validator: + (value) => value == null || value.isEmpty ? errorTextField : null, ); await tester.pumpWidget(buildTestableFieldWidget(testWidget)); @@ -56,8 +58,9 @@ void main() { expect(find.text(errorTextField), findsNothing); }); - testWidgets('should custom error text when invalidate field', - (WidgetTester tester) async { + testWidgets('should custom error text when invalidate field', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; const errorTextField = 'error text field'; final textFieldKey = GlobalKey(); @@ -76,8 +79,9 @@ void main() { expect(find.text(errorTextField), findsOneWidget); }); - testWidgets('should not show error text when some option is selected', - (WidgetTester tester) async { + testWidgets('should not show error text when some option is selected', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; final textFieldKey = GlobalKey(); const errorTextField = 'error text field'; @@ -88,8 +92,8 @@ void main() { FormBuilderFieldOption(value: 'AM'), FormBuilderFieldOption(value: 'PM'), ], - validator: (value) => - value == null || value.isEmpty ? errorTextField : null, + validator: + (value) => value == null || value.isEmpty ? errorTextField : null, ); await tester.pumpWidget(buildTestableFieldWidget(testWidget)); @@ -145,28 +149,29 @@ void main() { expect(textFieldKey.currentState?.value, equals(initialValue)); }); testWidgets( - 'Should reset custom error when invalidate field and then reset', - (tester) async { - const widgetName = 'sc1'; - final textFieldKey = GlobalKey(); - const errorTextField = 'error text field'; - final testWidget = FormBuilderCupertinoSlidingSegmentedControl( - name: widgetName, - key: textFieldKey, - options: const [ - FormBuilderFieldOption(value: 'AM'), - FormBuilderFieldOption(value: 'PM'), - ], - ); - await tester.pumpWidget(buildTestableFieldWidget(testWidget)); - - textFieldKey.currentState?.invalidate(errorTextField); - await tester.pumpAndSettle(); - - // Reset custom error - textFieldKey.currentState?.reset(); - await tester.pumpAndSettle(); - expect(find.text(errorTextField), findsNothing); - }); + 'Should reset custom error when invalidate field and then reset', + (tester) async { + const widgetName = 'sc1'; + final textFieldKey = GlobalKey(); + const errorTextField = 'error text field'; + final testWidget = FormBuilderCupertinoSlidingSegmentedControl( + name: widgetName, + key: textFieldKey, + options: const [ + FormBuilderFieldOption(value: 'AM'), + FormBuilderFieldOption(value: 'PM'), + ], + ); + await tester.pumpWidget(buildTestableFieldWidget(testWidget)); + + textFieldKey.currentState?.invalidate(errorTextField); + await tester.pumpAndSettle(); + + // Reset custom error + textFieldKey.currentState?.reset(); + await tester.pumpAndSettle(); + expect(find.text(errorTextField), findsNothing); + }, + ); }); } diff --git a/test/src/fields/form_builder_cupertino_switch_test.dart b/test/src/fields/form_builder_cupertino_switch_test.dart index e22b7f8..69c561a 100644 --- a/test/src/fields/form_builder_cupertino_switch_test.dart +++ b/test/src/fields/form_builder_cupertino_switch_test.dart @@ -6,8 +6,9 @@ import '../form_builder_tester.dart'; void main() { group('initialValue -', () { - testWidgets('should initial value when set initialValue', - (WidgetTester tester) async { + testWidgets('should initial value when set initialValue', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; final switchKey = GlobalKey(); final testWidget = FormBuilderCupertinoSwitch( @@ -22,8 +23,9 @@ void main() { }); group('errors -', () { - testWidgets('should error text when value is false', - (WidgetTester tester) async { + testWidgets('should error text when value is false', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; const errorTextField = 'error text field'; final switchKey = GlobalKey(); @@ -47,8 +49,9 @@ void main() { expect(find.text(errorTextField), findsNothing); }); - testWidgets('should custom error text when invalidate field', - (WidgetTester tester) async { + testWidgets('should custom error text when invalidate field', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; const errorTextField = 'error text field'; final switchKey = GlobalKey(); @@ -63,8 +66,9 @@ void main() { expect(find.text(errorTextField), findsOneWidget); }); - testWidgets('should not show error text when value is true', - (WidgetTester tester) async { + testWidgets('should not show error text when value is true', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; final switchKey = GlobalKey(); const errorTextField = 'error text field'; @@ -119,24 +123,25 @@ void main() { expect(switchKey.currentState?.value, equals(initialValue)); }); testWidgets( - 'Should reset custom error when invalidate field and then reset', - (tester) async { - const widgetName = 'sc1'; - final switchKey = GlobalKey(); - const errorTextField = 'error text field'; - final testWidget = FormBuilderCupertinoSwitch( - name: widgetName, - key: switchKey, - ); - await tester.pumpWidget(buildTestableFieldWidget(testWidget)); - - switchKey.currentState?.invalidate(errorTextField); - await tester.pumpAndSettle(); - - // Reset custom error - switchKey.currentState?.reset(); - await tester.pumpAndSettle(); - expect(find.text(errorTextField), findsNothing); - }); + 'Should reset custom error when invalidate field and then reset', + (tester) async { + const widgetName = 'sc1'; + final switchKey = GlobalKey(); + const errorTextField = 'error text field'; + final testWidget = FormBuilderCupertinoSwitch( + name: widgetName, + key: switchKey, + ); + await tester.pumpWidget(buildTestableFieldWidget(testWidget)); + + switchKey.currentState?.invalidate(errorTextField); + await tester.pumpAndSettle(); + + // Reset custom error + switchKey.currentState?.reset(); + await tester.pumpAndSettle(); + expect(find.text(errorTextField), findsNothing); + }, + ); }); } diff --git a/test/src/fields/form_builder_cupertino_text_field_test.dart b/test/src/fields/form_builder_cupertino_text_field_test.dart index 97728c7..0f0b2b2 100644 --- a/test/src/fields/form_builder_cupertino_text_field_test.dart +++ b/test/src/fields/form_builder_cupertino_text_field_test.dart @@ -6,8 +6,9 @@ import '../form_builder_tester.dart'; void main() { group('initialValue -', () { - testWidgets('should initial value when set initialValue', - (WidgetTester tester) async { + testWidgets('should initial value when set initialValue', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; final textFieldKey = GlobalKey(); final testWidget = FormBuilderCupertinoTextField( @@ -22,16 +23,17 @@ void main() { }); group('errors -', () { - testWidgets('should error text when value is empty', - (WidgetTester tester) async { + testWidgets('should error text when value is empty', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; const errorTextField = 'error text field'; final textFieldKey = GlobalKey(); final testWidget = FormBuilderCupertinoTextField( name: widgetName, key: textFieldKey, - validator: (value) => - value == null || value.isEmpty ? errorTextField : null, + validator: + (value) => value == null || value.isEmpty ? errorTextField : null, ); await tester.pumpWidget(buildTestableFieldWidget(testWidget)); @@ -48,8 +50,9 @@ void main() { expect(find.text(errorTextField), findsNothing); }); - testWidgets('should custom error text when invalidate field', - (WidgetTester tester) async { + testWidgets('should custom error text when invalidate field', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; const errorTextField = 'error text field'; final textFieldKey = GlobalKey(); @@ -64,16 +67,17 @@ void main() { expect(find.text(errorTextField), findsOneWidget); }); - testWidgets('should not show error text when value is true', - (WidgetTester tester) async { + testWidgets('should not show error text when value is true', ( + WidgetTester tester, + ) async { const widgetName = 'sc1'; final textFieldKey = GlobalKey(); const errorTextField = 'error text field'; final testWidget = FormBuilderCupertinoTextField( name: widgetName, key: textFieldKey, - validator: (value) => - value == null || value.isEmpty ? errorTextField : null, + validator: + (value) => value == null || value.isEmpty ? errorTextField : null, ); await tester.pumpWidget(buildTestableFieldWidget(testWidget)); @@ -121,24 +125,25 @@ void main() { expect(textFieldKey.currentState?.value, equals(initialValue)); }); testWidgets( - 'Should reset custom error when invalidate field and then reset', - (tester) async { - const widgetName = 'sc1'; - final textFieldKey = GlobalKey(); - const errorTextField = 'error text field'; - final testWidget = FormBuilderCupertinoTextField( - name: widgetName, - key: textFieldKey, - ); - await tester.pumpWidget(buildTestableFieldWidget(testWidget)); - - textFieldKey.currentState?.invalidate(errorTextField); - await tester.pumpAndSettle(); - - // Reset custom error - textFieldKey.currentState?.reset(); - await tester.pumpAndSettle(); - expect(find.text(errorTextField), findsNothing); - }); + 'Should reset custom error when invalidate field and then reset', + (tester) async { + const widgetName = 'sc1'; + final textFieldKey = GlobalKey(); + const errorTextField = 'error text field'; + final testWidget = FormBuilderCupertinoTextField( + name: widgetName, + key: textFieldKey, + ); + await tester.pumpWidget(buildTestableFieldWidget(testWidget)); + + textFieldKey.currentState?.invalidate(errorTextField); + await tester.pumpAndSettle(); + + // Reset custom error + textFieldKey.currentState?.reset(); + await tester.pumpAndSettle(); + expect(find.text(errorTextField), findsNothing); + }, + ); }); }