Skip to content

Commit

Permalink
Merge pull request #1 from chrisjenx/cj/gh-actions
Browse files Browse the repository at this point in the history
add checks xml
  • Loading branch information
chrisjenx authored Jul 25, 2024
2 parents a2a7b42 + 656d609 commit 85d0155
Show file tree
Hide file tree
Showing 8 changed files with 371 additions and 54 deletions.
77 changes: 77 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: Checks
on:
push:
branches:
- main
pull_request:
branches:
- main
permissions:
checks: write
jobs:
Checks-JS:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Java JDK
uses: actions/[email protected]
with:
distribution: 'zulu'
java-version: '21'
cache: 'gradle'
- name: Setup Chrome
uses: browser-actions/[email protected]
- name: Run Js tests
run: ./gradlew jsBrowserTest --warn --continue
- name: Run Wasm tests
run: ./gradlew wasmJsBrowserTest --warn --continue
- name: Publish Test Report
uses: mikepenz/action-junit-report@v4
if: success() || failure()
with:
report_paths: '**/build/test-results/**/TEST-*.xml'
check_name: 'JS JUnit Test Report'
require_tests: true
Checks-Jvm:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Java JDK
uses: actions/[email protected]
with:
distribution: 'zulu'
java-version: '21'
cache: 'gradle'
- name: Run Android tests
run: ./gradlew :library:testDebugUnitTest --warn --continue
- name: Run Jvm tests
run: ./gradlew :library:jvmTest --warn --continue
- name: Publish Test Report
uses: mikepenz/action-junit-report@v4
if: success() || failure() # always run even if the previous step fails
with:
report_paths: '**/build/test-results/**/TEST-*.xml'
check_name: 'JVM JUnit Test Report'
require_tests: true
Checks-Apple:
runs-on: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Java JDK
uses: actions/[email protected]
with:
distribution: 'zulu'
java-version: '21'
cache: 'gradle'
- name: Run Apple tests
run: ./gradlew :library:iosSimulatorArm64Test --warn --continue
- name: Publish Test Report
uses: mikepenz/action-junit-report@v4
if: success() || failure() # always run even if the previous step fails
with:
report_paths: '**/build/test-results/**/TEST-*.xml'
check_name: 'Apple JUnit Test Report'
require_tests: true
47 changes: 40 additions & 7 deletions README.MD
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Yet Another Kotlin Compose Validation library

![Maven Central Version](https://img.shields.io/maven-central/v/com.chrisjenx.yakcov/library)

`TextField` validation is a pain, hopefully this is a bit easier

```kotlin
Expand All @@ -10,19 +12,50 @@ with(emailValiator) {
OutlinedTextField(
value = value,
onValueChange = ::validate,
modifier = Modifier.validateFocusChanged().fillMaxWidth(),
modifier = Modifier
.validateFocusChanged() // will start validation on loss of focus
.shakeOnInvalid() // will shake the field when invalid and validate() is called
.fillMaxWidth(),
label = { Text("Email*") },
placeholder = { Text("Email") },
leadingIcon = { Icon(Icons.Default.Email, contentDescription = "Email") },
isError = isError(),
supportingText = supportingText(),
isError = isError(), // will mark the field error when validation has started and is invalid
supportingText = supportingText(), // will show the validation message, or error message
)
}
```

## Before running!
- check your system with [KDoctor](https://github.com/Kotlin/kdoctor)
- install JDK 17 or higher on your machine
## Dependencies

By default we publish
to [Maven Central](https://central.sonatype.com/artifact/com.chrisjenx.yakcov/library).

We publish all targets (Android, JVM, JS, Wasm, iOS) you can include the common library in your
project and
it will pull in the correct target for what ever targets you have specified.

```kotlin
commonMain {
dependencies {
implementation("com.chrisjenx.yakcov:library:${version}")
}
}
```

If you only need a specific target you can include that directly, for example for Android:

```kotlin
dependencies {
implementation("com.chrisjenx.yakcov:library-android:${version}")
}
```

## Build locally

- check your system with [KDoctor](https://github.com/Kotlin/kdoctor)
- install JDK 17 or higher on your machine

## Testing
- run tests with `./gradlew test`

- You will need Chrome installed for JS based tests to run
- run tests with `./gradlew :library:test`
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ android.nonTransitiveRClass=true
#KMM
kotlin.mpp.androidGradlePluginCompatibility.nowarn=true
kotlin.apple.xcodeCompatibility.nowarn=true
kotlin.native.ignoreDisabledTargets=true

#Compose
org.jetbrains.compose.experimental.jscanvas.enabled=true
20 changes: 13 additions & 7 deletions library/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@file:OptIn(ExperimentalWasmDsl::class)

import com.android.build.api.dsl.ManagedVirtualDevice
import com.vanniktech.maven.publish.SonatypeHost
import org.jetbrains.compose.ExperimentalComposeLibrary
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
Expand Down Expand Up @@ -149,18 +150,23 @@ publishing {
maven {
name = "githubPackages"
url = uri("https://maven.pkg.github.com/chrisjenx/yakcov")
credentials(PasswordCredentials::class) {
username = project.findProperty("githubPackagesUsername") as String
password = project.findProperty("githubPackagesPassword") as String
}
credentials(PasswordCredentials::class)
// https://vanniktech.github.io/gradle-maven-publish-plugin/other/#configuring-the-repository
// username is from: githubPackagesUsername or ORG_GRADLE_PROJECT_githubPackagesUsername
// password is from: githubPackagesPassword or ORG_GRADLE_PROJECT_githubPackagesPassword
}
}
}

mavenPublishing {
coordinates("com.chrisjenx.yakcov", "library", "1.0.0-SNAPSHOT")
// get git shortSha for version
@Suppress("UnstableApiUsage")
val gitSha = providers.exec { commandLine("git", "rev-parse", "--short", "HEAD") }
.standardOutput.asText.map { it.trim() }

// the following is optional
mavenPublishing {
coordinates("com.chrisjenx.yakcov", "library", "1.0.0-${gitSha.get()}")
publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL)
signAllPublications()

pom {
name.set("Yakcov")
Expand Down
83 changes: 83 additions & 0 deletions library/src/commonMain/kotlin/com/chrisjenx/yakcov/ShakingState.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.chrisjenx.yakcov

import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.AnimationSpec
import androidx.compose.animation.core.tween
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer

class ShakingState(
private val strength: Strength,
private val direction: Direction
) {

val xPosition = Animatable(0f)

suspend fun shake(animationDuration: Int = 50) {
val shakeAnimationSpec: AnimationSpec<Float> = tween(animationDuration)
when (direction) {
Direction.LEFT -> shakeToLeft(shakeAnimationSpec)
Direction.RIGHT -> shakeToRight(shakeAnimationSpec)
Direction.LEFT_THEN_RIGHT -> shakeToLeftThenRight(shakeAnimationSpec)
Direction.RIGHT_THEN_LEFT -> shakeToRightThenLeft(shakeAnimationSpec)
}
}

private suspend fun shakeToLeft(shakeAnimationSpec: AnimationSpec<Float>) {
repeat(3) {
xPosition.animateTo(-strength.value, shakeAnimationSpec)
xPosition.animateTo(0f, shakeAnimationSpec)
}
}

private suspend fun shakeToRight(shakeAnimationSpec: AnimationSpec<Float>) {
repeat(3) {
xPosition.animateTo(strength.value, shakeAnimationSpec)
xPosition.animateTo(0f, shakeAnimationSpec)
}
}

private suspend fun shakeToRightThenLeft(shakeAnimationSpec: AnimationSpec<Float>) {
repeat(3) {
xPosition.animateTo(strength.value, shakeAnimationSpec)
xPosition.animateTo(0f, shakeAnimationSpec)
xPosition.animateTo(-strength.value / 2, shakeAnimationSpec)
xPosition.animateTo(0f, shakeAnimationSpec)
}
}

private suspend fun shakeToLeftThenRight(shakeAnimationSpec: AnimationSpec<Float>) {
repeat(3) {
xPosition.animateTo(-strength.value, shakeAnimationSpec)
xPosition.animateTo(0f, shakeAnimationSpec)
xPosition.animateTo(strength.value / 2, shakeAnimationSpec)
xPosition.animateTo(0f, shakeAnimationSpec)
}
}

sealed class Strength(val value: Float) {
data object Normal : Strength(17f)
data object Strong : Strength(40f)
data class Custom(val strength: Float) : Strength(strength)
}

enum class Direction {
LEFT, RIGHT, LEFT_THEN_RIGHT, RIGHT_THEN_LEFT
}
}

@Composable
fun rememberShakingState(
strength: ShakingState.Strength = ShakingState.Strength.Normal,
direction: ShakingState.Direction = ShakingState.Direction.LEFT
): ShakingState {
return remember { ShakingState(strength = strength, direction = direction) }
}

fun Modifier.shakable(state: ShakingState): Modifier {
return graphicsLayer {
translationX = state.xPosition.value
}
}
Loading

0 comments on commit 85d0155

Please sign in to comment.