diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 971da32..28eb99c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -8,11 +8,12 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up JDK 12 - uses: actions/setup-java@v1 + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 with: - java-version: 12 + java-version: 17 + distribution: 'temurin' - name: Grant execute permission for gradlew run: chmod +x gradlew @@ -24,4 +25,4 @@ jobs: with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} BRANCH: gh-pages - FOLDER: ./form-builder/build/dokka/html \ No newline at end of file + FOLDER: ./form-builder/build/dokka/html diff --git a/README.md b/README.md index 331158c..5ccf33e 100644 --- a/README.md +++ b/README.md @@ -12,17 +12,17 @@ support for a form state so the library is used to provide a custom implementati In the root `build.gradle` file add the following: -```groovy +```kotlin repositories { - maven { url "https://jitpack.io" } + maven { url = uri("https://jitpack.io") } } ``` Then add the following to your module's `build.gradle` -```groovy +```kotlin dependencies { - implementation 'com.github.jkuatdsc:form-builder:${version}' + implementation("com.github.jkuatdsc:form-builder:${version}") } ``` diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 7c66709..0000000 --- a/build.gradle +++ /dev/null @@ -1,19 +0,0 @@ -buildscript { - ext { - kotlin_version = '1.7.0' - compose_version = '1.2.0' - } - repositories { - google() - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' - classpath "org.jetbrains.dokka:dokka-gradle-plugin:$kotlin_version" - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -task clean(type: Delete) { - delete rootProject.buildDir -} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..c524f0b --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + alias(libs.plugins.android.library) apply false + alias(libs.plugins.android.application) apply false + alias(libs.plugins.jetbrains.kotlin.android) apply false + alias(libs.plugins.jetbrains.dokka) apply false + alias(libs.plugins.jetbrains.compose.compiler) apply false +} diff --git a/example/build.gradle b/example/build.gradle deleted file mode 100644 index 991b35c..0000000 --- a/example/build.gradle +++ /dev/null @@ -1,64 +0,0 @@ -plugins { - id 'com.android.application' - id 'kotlin-android' -} - -android { - compileSdk 33 - - defaultConfig { - applicationId "com.dsc.formbuilder" - minSdk 27 - targetSdk 33 - versionCode 1 - versionName "1.0" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } - buildFeatures { - compose true - } - composeOptions { - kotlinCompilerExtensionVersion compose_version - } - packagingOptions { - resources { - excludes += '/META-INF/{AL2.0,LGPL2.1}' - } - } -} - -dependencies { - - implementation project(':form-builder') - - implementation 'androidx.core:core-ktx:1.8.0' - implementation 'androidx.appcompat:appcompat:1.5.0' - implementation 'androidx.activity:activity-compose:1.5.1' - implementation 'com.google.android.material:material:1.6.1' - implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' - - implementation "androidx.compose.ui:ui:$compose_version" - implementation "androidx.compose.material:material:$compose_version" - implementation "androidx.compose.animation:animation:$compose_version" - implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" - - debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" - - implementation("androidx.compose.material3:material3:1.0.0-beta01") - implementation("androidx.compose.material3:material3-window-size-class:1.0.0-beta01") -} \ No newline at end of file diff --git a/example/build.gradle.kts b/example/build.gradle.kts new file mode 100644 index 0000000..34e1dc2 --- /dev/null +++ b/example/build.gradle.kts @@ -0,0 +1,71 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.jetbrains.kotlin.android) + alias(libs.plugins.jetbrains.compose.compiler) +} + +android { + compileSdk = libs.versions.compileSdk.get().toInt() + + defaultConfig { + applicationId = "com.dsc.formbuilder" + minSdk = libs.versions.minSdk.get().toInt() + targetSdk = libs.versions.targetSdk.get().toInt() + versionCode = libs.versions.appVersionCode.get().toInt() + versionName = libs.versions.appVersionName.get() + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + getByName("release") { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility(libs.versions.jvmTarget.get()) + targetCompatibility(libs.versions.jvmTarget.get()) + isCoreLibraryDesugaringEnabled = true + } + + kotlin { + jvmToolchain(libs.versions.jvmTarget.get().toInt()) + } + buildFeatures { + compose = true + } + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } + namespace = "com.dsc.formbuilder" +} + +dependencies { + + implementation(project(":form-builder")) + // For using modern java 8 classes with older versions of android + coreLibraryDesugaring(libs.core.java8) + + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.appcompat) + implementation(libs.androidx.activity.compose) + implementation(libs.android.material) + implementation(libs.androidx.lifecycle.runtime) + + implementation(libs.androidx.compose.ui) + implementation(libs.androidx.compose.material) + implementation(libs.androidx.compose.animation) + implementation(libs.androidx.compose.ui.tooling.preview) + + debugImplementation(libs.androidx.compose.ui.tooling) + + implementation(libs.androidx.compose.material3) + implementation(libs.androidx.compose.material3.window.size) +} \ No newline at end of file diff --git a/example/proguard-rules.pro b/example/proguard-rules.pro index 481bb43..ff59496 100644 --- a/example/proguard-rules.pro +++ b/example/proguard-rules.pro @@ -1,6 +1,6 @@ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. +# proguardFiles setting in build.gradle.kts. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html diff --git a/example/src/main/AndroidManifest.xml b/example/src/main/AndroidManifest.xml index 3a17566..a176e9a 100644 --- a/example/src/main/AndroidManifest.xml +++ b/example/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + >) { - - val genderState: ChoiceState = formState.getState("gender") - val experienceState: ChoiceState = formState.getState("experience") - val osState: ChoiceState = formState.getState("os") - - - val genderOptions = listOf("Non-binary", "Male", "Female") - val experienceOptions = listOf("1-3 Years", "3-5 Years", "5+ Years") - val osOptions = listOf("Mac OS", "Linux", "Windows") - - Column(horizontalAlignment = CenterHorizontally, verticalArrangement = Center) { - Text( - modifier = Modifier.fillMaxWidth(), - text = "Other Details", - style = MaterialTheme.typography.h6 - ) - - Spacer(modifier = Modifier.height(30.dp)) - - OtherDetailsRow(labelText = "Gender", items = genderOptions, genderState) - OtherDetailsRow(labelText = "Experience", items = experienceOptions, experienceState) - OtherDetailsRow(labelText = "Using OS", items = osOptions, osState) - } + + val genderState: ChoiceState = formState.getState("gender") + val experienceState: ChoiceState = formState.getState("experience") + val osState: ChoiceState = formState.getState("os") + + + val genderOptions = listOf( + "Non-binary", + "Male", + "Female" + ) + val experienceOptions = listOf( + "1-3 Years", + "3-5 Years", + "5+ Years" + ) + val osOptions = listOf( + "Mac OS", + "Linux", + "Windows" + ) + + Column( + horizontalAlignment = CenterHorizontally, + verticalArrangement = Center + ) { + Text( + modifier = Modifier.fillMaxWidth(), + text = "Other Details", + style = MaterialTheme.typography.h6 + ) + + Spacer(modifier = Modifier.height(30.dp)) + + OtherDetailsRow( + labelText = "Gender", + items = genderOptions, + genderState + ) + OtherDetailsRow( + labelText = "Experience", + items = experienceOptions, + experienceState + ) + OtherDetailsRow( + labelText = "Using OS", + items = osOptions, + osState + ) + } } @Composable -fun OtherDetailsRow(labelText: String, items: List, state: ChoiceState) { - Column { - Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { - Text(text = labelText, style = MaterialTheme.typography.body1) - - Spacer(modifier = Modifier.weight(1f)) - - items.forEach { item -> - Column( - modifier = Modifier.width(85.dp).selectableGroup(), - verticalArrangement = Center, - horizontalAlignment = CenterHorizontally - ) { - Text( - text = item, style = MaterialTheme.typography.caption - ) - RadioButton( - selected = state.value == item, - onClick = { state.change(item) }, - colors = RadioButtonDefaults.colors( - unselectedColor = MaterialTheme.colors.onPrimary, - selectedColor = MaterialTheme.colors.onPrimary - ) - ) - } - } - } - - if (state.hasError) { - Text( - text = state.errorMessage, - style = MaterialTheme.typography.caption.copy( - color = MaterialTheme.colors.error - ) - ) - } - } +fun OtherDetailsRow( + labelText: String, + items: List, + state: ChoiceState +) { + Column { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = labelText, + style = MaterialTheme.typography.body1 + ) + + Spacer(modifier = Modifier.weight(1f)) + + items.forEach { item -> + Column( + modifier = Modifier + .width(85.dp) + .selectableGroup(), + verticalArrangement = Center, + horizontalAlignment = CenterHorizontally + ) { + Text( + text = item, + style = MaterialTheme.typography.caption + ) + RadioButton( + selected = state.value == item, + onClick = { state.change(item) }, + colors = RadioButtonDefaults.colors( + unselectedColor = MaterialTheme.colors.onPrimary, + selectedColor = MaterialTheme.colors.onPrimary + ) + ) + } + } + } + + if (state.hasError) { + Text( + text = state.errorMessage, + style = MaterialTheme.typography.caption.copy( + color = MaterialTheme.colors.error + ) + ) + } + } } @Preview @Composable fun OtherDetailsPreview() { - val formState: FormState> = FormState( - listOf( - ChoiceState("gender", validators = listOf()), - ChoiceState("experience", validators = listOf()), - ChoiceState("os", validators = listOf()) - ) - ) - FormBuilderTheme { - Surface(color = MaterialTheme.colors.background) { - OtherDetails(formState) - } - } + val formState: FormState> = FormState( + listOf( + ChoiceState( + "gender", + validators = listOf() + ), + ChoiceState( + "experience", + validators = listOf() + ), + ChoiceState( + "os", + validators = listOf() + ) + ) + ) + FormBuilderTheme { + Surface(color = MaterialTheme.colors.background) { + OtherDetails(formState) + } + } } \ No newline at end of file diff --git a/form-builder/build.gradle.kts b/form-builder/build.gradle.kts new file mode 100644 index 0000000..fd215ff --- /dev/null +++ b/form-builder/build.gradle.kts @@ -0,0 +1,82 @@ +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.jetbrains.kotlin.android) + alias(libs.plugins.jetbrains.dokka) + alias(libs.plugins.jetbrains.compose.compiler) + id("maven-publish") +} + +android { + compileSdk = libs.versions.compileSdk.get().toInt() + + defaultConfig { + minSdk = libs.versions.minSdk.get().toInt() + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + getByName("release") { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + + compileOptions { + sourceCompatibility(libs.versions.jvmTarget.get()) + targetCompatibility(libs.versions.jvmTarget.get()) + isCoreLibraryDesugaringEnabled = true + } + + kotlin { + jvmToolchain(libs.versions.jvmTarget.get().toInt()) + } + + testOptions { + unitTests { + all { + it.useJUnitPlatform() + } + } + } + + buildFeatures { + compose = true + } + namespace = "com.dsc.form_builder" +} + +dependencies { + // Testing + testImplementation(libs.junit.jupiter) + testImplementation(libs.mockito.kotlin) + testImplementation(libs.junit.jupiter.params) + + // Compose + implementation(libs.androidx.activity.compose) + + // Kotlin reflection + implementation(libs.jetbrains.kotlin.reflection) + + // For using modern java 8 classes with older versions of android + coreLibraryDesugaring(libs.core.java8) +} + + + +afterEvaluate { + publishing { + publications { + create("release") { + from(components["release"]) + + groupId = "com.github.dsc-jkuat" + artifactId = "form-builder" + version = libs.versions.libVersionName.get() + } + } + } +} diff --git a/form-builder/proguard-rules.pro b/form-builder/proguard-rules.pro index 481bb43..ff59496 100644 --- a/form-builder/proguard-rules.pro +++ b/form-builder/proguard-rules.pro @@ -1,6 +1,6 @@ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. +# proguardFiles setting in build.gradle.kts. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html diff --git a/form-builder/src/main/AndroidManifest.xml b/form-builder/src/main/AndroidManifest.xml index f8a8341..44008a4 100644 --- a/form-builder/src/main/AndroidManifest.xml +++ b/form-builder/src/main/AndroidManifest.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/form-builder/src/main/java/com/dsc/form_builder/SwitchState.kt b/form-builder/src/main/java/com/dsc/form_builder/SwitchState.kt new file mode 100755 index 0000000..00f9171 --- /dev/null +++ b/form-builder/src/main/java/com/dsc/form_builder/SwitchState.kt @@ -0,0 +1,99 @@ +package com.dsc.form_builder + +import androidx.annotation.VisibleForTesting +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue + +/** + * This class represents the state of a switch form field. + * It extends [BaseState] and manages the state and validations for switch inputs. + * + * @param name The name of the field used to access the state when required in the form. + * @param initial The initial value/state of the switch. By default, it is false (off). + * @param transform An optional function used to change the [Boolean] data type of the switch to a suitable type. + * @param validators This is the list of [Validators] that are used to validate the switch state. + * By default, the switch states will have an empty list. You can override this + * and provide your own list of validators. + * + * @author [Nenoeldeeb] + * @created [01/09/2024] + */ +class SwitchState( + name: String, + initial: Boolean = false, + transform: Transform? = null, + validators: List = listOf(), +) : BaseState( + initial = initial, + name = name, + transform = transform, + validators = validators +) { + + /** + * The current value of the switch. It uses [mutableStateOf] to make it observable in Compose. + */ + override var value: Boolean by mutableStateOf(initial) + + /** + * Toggles the state of the switch between true (on) and false (off). + * This function also clears any previous error state by calling [hideError]. + */ + fun toggle() { + hideError() + value = !value + } + + /** + * Validates the switch state based on the provided validators. + * This function is called by [FormState] to confirm whether the switch field is valid. + * + * @return true if all validations pass, false otherwise. + */ + override fun validate(): Boolean { + val validations = validators.map { + when (it) { + is Validators.Required -> validateRequired(it.message) + is Validators.Custom -> validateCustom( + it.function, + it.message + ) + + else -> throw Exception("${it::class.simpleName} validator cannot be called on switch state. Did you mean Validators.Custom?") + } + } + return validations.all { it } + } + + /** + * Validates if the switch is in the required state (typically on/true). + * + * @param message The error message to display if the validation fails. + * @return true if the switch is in the required state, false otherwise. + */ + @VisibleForTesting + internal fun validateRequired(message: String): Boolean { + // For a switch, "required" typically means it must be turned on + val valid = value + if (!valid) showError(message) + return valid + } + + /** + * Allows for custom validation of the switch state. + * + * @param function A lambda that takes a Boolean and returns a Boolean. + * It should return true if the validation passes, false otherwise. + * @param message The error message to display if the validation fails. + * @return The result of the custom validation function. + */ + private fun validateCustom( + function: (Boolean) -> Boolean, + message: String + ): Boolean { + val valid = function(value) + if (!valid) showError(message) + return valid + } +} \ No newline at end of file diff --git a/form-builder/src/main/java/com/dsc/form_builder/TextFieldState.kt b/form-builder/src/main/java/com/dsc/form_builder/TextFieldState.kt index 225b1f7..10f1cd7 100644 --- a/form-builder/src/main/java/com/dsc/form_builder/TextFieldState.kt +++ b/form-builder/src/main/java/com/dsc/form_builder/TextFieldState.kt @@ -195,7 +195,7 @@ open class TextFieldState( * @param message the error message passed to [showError] to display if the [value] is empty. By default we use the [REQUIRED_MESSAGE] constant. */ internal fun validateRequired(message: String): Boolean { - val valid = value.isNotEmpty() + val valid = value.isNotBlank() if (!valid) showError(message) return valid } diff --git a/form-builder/src/test/java/com/dsc/form_builder/FormStateTest.kt b/form-builder/src/test/java/com/dsc/form_builder/FormStateTest.kt old mode 100644 new mode 100755 index f95a377..9a82c49 --- a/form-builder/src/test/java/com/dsc/form_builder/FormStateTest.kt +++ b/form-builder/src/test/java/com/dsc/form_builder/FormStateTest.kt @@ -5,38 +5,46 @@ import org.junit.jupiter.api.Test internal class FormStateTest { - @Nested - inner class DescribingFormState { - private val formState = FormState( - listOf( - TextFieldState(name = "email"), - SelectState(name = "hobbies"), - ChoiceState(name = "gender"), - TextFieldState(name = "age", initial = "34") - ) - ) - - private val emailState = formState.getState("email") - private val hobbyState = formState.getState("hobbies") - private val genderState = formState.getState("gender") - private val ageState = formState.getState("age") - - @Test - fun `state should be reset to initial values`() { - // Given a form state with values changed - emailState.change("buider@gmail.com") - hobbyState.select("Running") - genderState.change("male") - ageState.change("56") - - // When the form.reset is requested - formState.reset() - - // Then all values are reset to the original state - assert(emailState.value == "" && !emailState.hasError) - assert(hobbyState.value == mutableListOf() && !hobbyState.hasError) - assert(genderState.value == "" && !genderState.hasError) - assert(ageState.value == "34" && !ageState.hasError) - } - } -} + @Nested + inner class DescribingFormState { + + private val formState = FormState( + listOf( + TextFieldState(name = "email"), + SelectState(name = "hobbies"), + ChoiceState(name = "gender"), + TextFieldState( + name = "age", + initial = "34" + ), + SwitchState(name = "active") + ) + ) + + private val emailState = formState.getState("email") + private val hobbyState = formState.getState("hobbies") + private val genderState = formState.getState("gender") + private val ageState = formState.getState("age") + private val statusState = formState.getState("active") + + @Test + fun `state should be reset to initial values`() { + // Given a form state with values changed + emailState.change("buider@gmail.com") + hobbyState.select("Running") + genderState.change("male") + ageState.change("56") + statusState.toggle() + + // When the form.reset is requested + formState.reset() + + // Then all values are reset to the original state + assert(emailState.value == "" && !emailState.hasError) + assert(hobbyState.value == mutableListOf() && !hobbyState.hasError) + assert(genderState.value == "" && !genderState.hasError) + assert(ageState.value == "34" && !ageState.hasError) + assert(!statusState.value && !statusState.hasError) + } + } +} \ No newline at end of file diff --git a/form-builder/src/test/java/com/dsc/form_builder/SwitchStateTest.kt b/form-builder/src/test/java/com/dsc/form_builder/SwitchStateTest.kt new file mode 100755 index 0000000..6094300 --- /dev/null +++ b/form-builder/src/test/java/com/dsc/form_builder/SwitchStateTest.kt @@ -0,0 +1,53 @@ +package com.dsc.form_builder + +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test + +internal class SwitchStateTest { + + @Nested + inner class DescribingStateChanges { + + private val classToTest: SwitchState = SwitchState(name = "test") + + @Test + fun `errors should be hidden when toggled`() { + // Simulate an existing validation error + classToTest.hasError = true + classToTest.errorMessage = "error message" + + classToTest.toggle() // When toggle is called + + assert(!classToTest.hasError) + assert(classToTest.errorMessage.isEmpty()) + } + + @Test + fun `state should be updated when toggled`() { + val initialState = classToTest.value + classToTest.toggle() // When toggle is called + + assert(classToTest.value != initialState) + + classToTest.toggle() // Toggle again + assert(classToTest.value == initialState) + } + } + + @Nested + inner class DescribingValidation { + + private val classToTest: SwitchState = SwitchState(name = "test") + + @Test + fun `Validators_Required works correctly`() { + // When state is false (off) + val firstValidation = classToTest.validateRequired("") + assert(!firstValidation) + + classToTest.toggle() // Turn on the switch + val secondValidation = classToTest.validateRequired("") + assert(secondValidation) + } + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 736c959..8dae799 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,17 +6,18 @@ # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +org.gradle.jvmargs=-Xmx4g -XX:+UseParallelGC -Dfile.encoding=UTF-8 # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true +org.gradle.parallel=true # AndroidX package structure to make it clearer which packages are bundled with the # Android operating system, and which are packaged with your app"s APK # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true -android.disableAutomaticComponentCreation=true # Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official \ No newline at end of file +kotlin.code.style=official +android.nonTransitiveRClass=false +android.nonFinalResIds=false \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..9dd615b --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,47 @@ +[versions] +activityCompose = "1.9.1" +agp = "8.5.2" +appcompat = "1.7.0" +appVersionCode = "1" +appVersionName = "1.0" +compileSdk = "34" +composeBom = "2024.08.00" +coreKtx = "1.13.1" +desugar = "2.1.2" +dokka = "1.9.20" +junit = "5.8.1" +jvmTarget = "17" +kotlin = "2.0.20" +libVersionName = "1.2.0" +lifecycleRuntimeKtx = "2.8.4" +material = "1.12.0" +minSdk = "24" +mockitoKotlin = "4.0.0" +targetSdk = "34" + +[libraries] +android-material = { group = "com.google.android.material", name = "material", version.ref = "material" } +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } +androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } +androidx-compose-animation = { group = "androidx.compose.animation", name = "animation" } +androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } +androidx-compose-material = { group = "androidx.compose.material", name = "material" } +androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } +androidx-compose-material3-window-size = { group = "androidx.compose.material3", name = "material3-window-size-class" } +androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" } +androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +androidx-lifecycle-runtime = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" } +core-java8 = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "desugar" } +jetbrains-kotlin-reflection = { group = "org.jetbrains.kotlin", name = "kotlin-reflect", version.ref = "kotlin" } +junit-jupiter = { group = "org.junit.jupiter", name = "junit-jupiter", version.ref = "junit" } +junit-jupiter-params = { group = "org.junit.jupiter", name = "junit-jupiter-params", version.ref = "junit" } +mockito-kotlin = { group = "org.mockito.kotlin", name = "mockito-kotlin", version.ref = "mockitoKotlin" } + +[plugins] +android-application = { id = "com.android.application", version.ref = "agp" } +android-library = { id = "com.android.library", version.ref = "agp" } +jetbrains-compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +jetbrains-dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e0120c0..483b6a7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Thu Feb 17 16:08:59 EAT 2022 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/jitpack.yml b/jitpack.yml index 1bfc0d7..f82bf6a 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -1,4 +1,4 @@ jdk: - - openjdk11 + - openjdk17 before_install: - - ./scripts/prepareJitpackEnvironment.sh \ No newline at end of file + - ./scripts/prepareJitpackEnvironment.sh diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 3375b63..0000000 --- a/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) - repositories { - google() - mavenCentral() - } -} -rootProject.name = "Form Builder" -include ':example' -include ':form-builder' diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..31255e5 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,23 @@ +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} +pluginManagement { + repositories { + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } + mavenCentral() + gradlePluginPortal() + } +} +rootProject.name = "Form Builder" +include(":example") +include(":form-builder")