From 0fee248dff765e7fc8f6f9a65d3954fbb81ca0f6 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Mon, 12 Oct 2026 13:31:22 +0200 Subject: [PATCH 1/2] chore: update AGP to 9.4.1 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5ac0fad..054c2d3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "9.4.0" +agp = "9.4.1" kotlinReflect = "1.7.10" kotlin = "2.4.10" kotlinxCoroutinesCore = "1.11.0" From c7f84d16fd07c030901d672875e21c2be23b7e84 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Mon, 12 Oct 2026 15:45:38 +0200 Subject: [PATCH 2/2] feat: add setFieldResult method to set external validation errors --- build.gradle.kts | 2 +- .../composeui/scope/FormFieldScope.kt | 16 +++++++++++++-- .../composeui/scope/FormFieldScopeImpl.kt | 4 ++++ .../de/thetadev/formconductor/FormField.kt | 14 ++++++++++++- .../thetadev/formconductor/FormFieldImpl.kt | 20 +++++++++++++++++++ .../rules/ExternalValidationErrorRule.kt | 3 +++ 6 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 core/src/main/java/de/thetadev/formconductor/validation/rules/ExternalValidationErrorRule.kt diff --git a/build.gradle.kts b/build.gradle.kts index 31bfd13..17835e9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,6 +6,6 @@ plugins { } allprojects { - version = "0.3.3" + version = "0.4.0" group = "de.thetadev.formconductor" } diff --git a/compose-ui/src/main/java/de/thetadev/formconductor/composeui/scope/FormFieldScope.kt b/compose-ui/src/main/java/de/thetadev/formconductor/composeui/scope/FormFieldScope.kt index ce49cb1..934c656 100644 --- a/compose-ui/src/main/java/de/thetadev/formconductor/composeui/scope/FormFieldScope.kt +++ b/compose-ui/src/main/java/de/thetadev/formconductor/composeui/scope/FormFieldScope.kt @@ -9,7 +9,7 @@ import de.thetadev.formconductor.FieldResult * * @param V type of field value */ -interface FormFieldScope { +interface FormFieldScope { /** * Observable State instance of field value @@ -30,7 +30,19 @@ interface FormFieldScope { * * You're encouraged to set the field value only using this function * - * @param input input value + * @param input Field value + * @param validate Validate the input on update */ fun setField(input: V?, validate: Boolean = true) + + /** + * A setter function for field value or error. + * + * Set the field value if the input is successful, fail validation if the input is an error. + * + * To be used for custom fields with built-in validation. + * + * @param input Field value or error + */ + fun setFieldResult(input: Result) } diff --git a/compose-ui/src/main/java/de/thetadev/formconductor/composeui/scope/FormFieldScopeImpl.kt b/compose-ui/src/main/java/de/thetadev/formconductor/composeui/scope/FormFieldScopeImpl.kt index 2a1ab19..fe196cf 100644 --- a/compose-ui/src/main/java/de/thetadev/formconductor/composeui/scope/FormFieldScopeImpl.kt +++ b/compose-ui/src/main/java/de/thetadev/formconductor/composeui/scope/FormFieldScopeImpl.kt @@ -21,4 +21,8 @@ internal class FormFieldScopeImpl( override fun setField(input: V?, validate: Boolean) { formField.setField(input, validate) } + + override fun setFieldResult(input: Result) { + formField.setFieldResult(input) + } } diff --git a/core/src/main/java/de/thetadev/formconductor/FormField.kt b/core/src/main/java/de/thetadev/formconductor/FormField.kt index a26f211..b944cb2 100644 --- a/core/src/main/java/de/thetadev/formconductor/FormField.kt +++ b/core/src/main/java/de/thetadev/formconductor/FormField.kt @@ -50,10 +50,22 @@ interface FormField { * * The function validates the field if the input is not **empty** or the field isn't **optional** * - * @param input + * @param input Field value + * @param validate Validate the input on update */ fun setField(input: V?, validate: Boolean = true) + /** + * A setter function for field value or error. + * + * Set the field value if the input is successful, fail validation if the input is an error. + * + * To be used for custom fields with built-in validation. + * + * @param input Field value or error + */ + fun setFieldResult(input: Result) + /** * Validate the field without updating its value * diff --git a/core/src/main/java/de/thetadev/formconductor/FormFieldImpl.kt b/core/src/main/java/de/thetadev/formconductor/FormFieldImpl.kt index 1fe249b..f9ac37c 100644 --- a/core/src/main/java/de/thetadev/formconductor/FormFieldImpl.kt +++ b/core/src/main/java/de/thetadev/formconductor/FormFieldImpl.kt @@ -1,6 +1,7 @@ package de.thetadev.formconductor import de.thetadev.formconductor.validation.optionalFlags.OptionalFlag +import de.thetadev.formconductor.validation.rules.ExternalValidationErrorRule import de.thetadev.formconductor.validation.rules.OptionalRule import de.thetadev.formconductor.validation.validators.FieldValidator import de.thetadev.formconductor.validation.validators.StatelessFieldValidator @@ -48,6 +49,7 @@ internal class FormFieldImpl( valueStream.value = input ?: defaultValue if (validate) { + if (hasExternalValidationError()) resultStream.value = FieldResult.NoInput validateField() } else if (input == null || input == "") { resultStream.value = FieldResult.NoInput @@ -56,10 +58,23 @@ internal class FormFieldImpl( } } + override fun setFieldResult(input: Result) { + input.fold( + onSuccess = { setField(it) }, + onFailure = { + resultStream.value = + FieldResult.Error("Validation error", ExternalValidationErrorRule) + } + ) + } + /** * Validates the current input value and updates the field's result */ override fun validateField(soft: Boolean) { + if (hasExternalValidationError()) { + return + } val input = valueStream.value // Null and empty strings are skipped for validation if (input != null && input != "") { @@ -110,4 +125,9 @@ internal class FormFieldImpl( optionalStateEvaluators.all(OptionalFlag::evaluate) } } + + private fun hasExternalValidationError(): Boolean { + val result = resultStream.value + return result is FieldResult.Error && result.failedRule is ExternalValidationErrorRule + } } diff --git a/core/src/main/java/de/thetadev/formconductor/validation/rules/ExternalValidationErrorRule.kt b/core/src/main/java/de/thetadev/formconductor/validation/rules/ExternalValidationErrorRule.kt new file mode 100644 index 0000000..117ce7e --- /dev/null +++ b/core/src/main/java/de/thetadev/formconductor/validation/rules/ExternalValidationErrorRule.kt @@ -0,0 +1,3 @@ +package de.thetadev.formconductor.validation.rules + +object ExternalValidationErrorRule : ValidationRule