Skip to content

Commit eb5040a

Browse files
committed
Introduce escape-handler module and use in tooltip + modal sheet
Remove used code
1 parent 5fbe2ea commit eb5040a

20 files changed

Lines changed: 226 additions & 180 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
- Split the primitives into modules. You can now pick and add only the primitives that you need instead of being forced to add the entire API in your codebase.
12+
- Introduced the following new modules: `composeunstyled-escape-handler`, `composeunstyled-build-modifier`
13+
1014
## [1.49.9] - 2025-04-24
1115

1216
### Fixed

composeunstyled-bottom-sheet/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ kotlin {
7979
val commonMain by getting {
8080
dependencies {
8181
implementation(libs.compose.foundation)
82-
implementation(projects.composeunstyledBuildmodifier)
82+
implementation(projects.composeunstyledBuildModifier)
8383
}
8484
}
8585

File renamed without changes.

composeunstyled-buildmodifier/src/commonMain/kotlin/com/composeunstyled/BuildModifier.kt renamed to composeunstyled-build-modifier/src/commonMain/kotlin/com/composeunstyled/BuildModifier.kt

File renamed without changes.
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
/*
2+
* Copyright (c) 2026 Composable Horizons
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
@file:Suppress("UnstableApiUsage")
23+
@file:OptIn(ExperimentalKotlinGradlePluginApi::class)
24+
25+
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
26+
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
27+
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree
28+
29+
plugins {
30+
alias(libs.plugins.compose)
31+
alias(libs.plugins.compose.compiler)
32+
alias(libs.plugins.kotlin.multiplatform)
33+
alias(libs.plugins.android.library)
34+
alias(libs.plugins.maven.publish)
35+
}
36+
37+
val publishGroupId = "com.composables"
38+
val publishVersion = libs.versions.unstyled.get()
39+
val githubUrl = "github.com/composablehorizons/compose-unstyled"
40+
val projectUrl = "https://composeunstyled.com"
41+
42+
java {
43+
toolchain {
44+
languageVersion = JavaLanguageVersion.of(17)
45+
}
46+
}
47+
48+
kotlin {
49+
compilerOptions {
50+
optIn.add("androidx.compose.ui.test.ExperimentalTestApi")
51+
freeCompilerArgs.add("-Xcontext-parameters")
52+
}
53+
androidTarget {
54+
publishLibraryVariants("release", "debug")
55+
compilerOptions {
56+
jvmTarget = JvmTarget.JVM_17
57+
}
58+
instrumentedTestVariant.sourceSetTree.set(KotlinSourceSetTree.test)
59+
}
60+
61+
jvm()
62+
63+
wasmJs {
64+
browser()
65+
}
66+
67+
js {
68+
browser()
69+
}
70+
71+
listOf(iosX64(), iosArm64(), iosSimulatorArm64()).forEach { iosTarget ->
72+
iosTarget.binaries.framework {
73+
baseName = "ComposeUnstyledEscapeHandler"
74+
isStatic = true
75+
}
76+
}
77+
78+
sourceSets {
79+
val commonMain by getting {
80+
dependencies {
81+
implementation(libs.compose.foundation)
82+
}
83+
}
84+
85+
androidMain.dependencies {
86+
implementation(libs.androidx.activitycompose)
87+
}
88+
89+
webMain.dependencies {
90+
implementation("org.jetbrains.kotlinx:kotlinx-browser:0.5.0")
91+
}
92+
93+
androidInstrumentedTest.dependencies {
94+
implementation(libs.androidx.compose.test)
95+
implementation(libs.androidx.compose.test.manifest)
96+
implementation(libs.androidx.espresso)
97+
implementation(project(":testcase"))
98+
}
99+
100+
commonTest.dependencies {
101+
implementation(kotlin("test"))
102+
implementation(project(":testcase"))
103+
104+
@OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
105+
implementation(libs.compose.ui.test)
106+
}
107+
108+
val jvmTest by getting
109+
110+
jvmTest.dependencies {
111+
implementation(libs.compose.ui.test.junit4)
112+
implementation(compose.desktop.currentOs) {
113+
exclude(group = "org.jetbrains.compose.material", module = "material")
114+
exclude(group = "org.jetbrains.compose.material", module = "material")
115+
}
116+
}
117+
118+
applyDefaultHierarchyTemplate {
119+
common {
120+
group("cmp") {
121+
withJvm()
122+
withIos()
123+
withWasmJs()
124+
withJs()
125+
}
126+
127+
group("web") {
128+
withWasmJs()
129+
withJs()
130+
}
131+
}
132+
}
133+
}
134+
}
135+
136+
android {
137+
namespace = "com.composeunstyled.escapehandler"
138+
compileSdk = libs.versions.android.compileSDK.get().toInt()
139+
defaultConfig {
140+
minSdk = libs.versions.android.minSDK.get().toInt()
141+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
142+
}
143+
}
144+
145+
group = publishGroupId
146+
version = publishVersion
147+
148+
mavenPublishing {
149+
publishToMavenCentral(automaticRelease = true, validateDeployment = false)
150+
if (project.hasProperty("signingInMemoryKeyId")) {
151+
signAllPublications()
152+
}
153+
154+
coordinates(
155+
groupId = publishGroupId,
156+
artifactId = "composeunstyled-escape-handler",
157+
version = publishVersion
158+
)
159+
160+
pom {
161+
name.set("Compose Unstyled Escape Handler")
162+
description.set("Escape and Back key handling primitives for Compose Multiplatform.")
163+
url.set(projectUrl)
164+
165+
licenses {
166+
license {
167+
name.set("MIT License")
168+
url.set("https://${githubUrl}/blob/main/LICENSE")
169+
}
170+
}
171+
172+
issueManagement {
173+
system.set("GitHub Issues")
174+
url.set("https://${githubUrl}/issues")
175+
}
176+
177+
developers {
178+
developer {
179+
id.set("composablehorizons")
180+
name.set("Composable Horizons")
181+
email.set("alex@composables.com")
182+
}
183+
}
184+
185+
scm {
186+
connection.set("scm:git:${githubUrl}.git")
187+
developerConnection.set("scm:git:ssh://${githubUrl}.git")
188+
url.set("https://${githubUrl}/tree/main")
189+
}
190+
}
191+
}

composeunstyled-primitives/src/androidMain/kotlin/com/composeunstyled/EscapeHandler.android.kt renamed to composeunstyled-escape-handler/src/androidMain/kotlin/com/composeunstyled/EscapeHandler.android.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ import androidx.activity.compose.BackHandler
2525
import androidx.compose.runtime.Composable
2626

2727
@Composable
28-
internal actual fun EscapeHandler(callback: () -> Unit) {
28+
actual fun EscapeHandler(callback: () -> Unit) {
2929
BackHandler { callback() }
3030
}

composeunstyled-tooltip/src/androidMain/kotlin/com/composeunstyled/KeyEventObserver.android.kt renamed to composeunstyled-escape-handler/src/androidMain/kotlin/com/composeunstyled/KeyEventObserver.android.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import androidx.compose.ui.input.key.KeyEvent
2929
import androidx.compose.ui.platform.LocalView
3030

3131
@Composable
32-
actual fun KeyEventObserver(onEvent: (KeyEvent) -> Boolean) {
32+
internal actual fun KeyEventObserver(onEvent: (KeyEvent) -> Boolean) {
3333
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
3434
val view = LocalView.current
3535

composeunstyled-primitives/src/cmpMain/kotlin/com/composeunstyled/EscapeHandler.cmp.kt renamed to composeunstyled-escape-handler/src/cmpMain/kotlin/com/composeunstyled/EscapeHandler.cmp.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,16 @@
2222
package com.composeunstyled
2323

2424
import androidx.compose.runtime.Composable
25+
import androidx.compose.ui.input.key.KeyEventType
2526
import androidx.compose.ui.input.key.Key
2627
import androidx.compose.ui.input.key.key
28+
import androidx.compose.ui.input.key.type
29+
30+
private val androidx.compose.ui.input.key.KeyEvent.isKeyDown: Boolean
31+
get() = type == KeyEventType.KeyDown
2732

2833
@Composable
29-
internal actual fun EscapeHandler(callback: () -> Unit) {
34+
actual fun EscapeHandler(callback: () -> Unit) {
3035
KeyEventObserver { event ->
3136
if (event.isKeyDown && (event.key == Key.Escape || event.key == Key.Back)) {
3237
callback()

composeunstyled-primitives/src/commonMain/kotlin/com/composeunstyled/EscapeHandler.kt renamed to composeunstyled-escape-handler/src/commonMain/kotlin/com/composeunstyled/EscapeHandler.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import androidx.compose.runtime.Composable
2828
/**
2929
* A multiplatform version of Android's BackHandler.
3030
*
31-
* On non-Android devices, the EscapeHandler calls the callback when Escape is pressed on the keyboard.
31+
* On non-Android devices, this can be implemented to react to Escape and Back key presses.
3232
*/
3333
@Composable
34-
internal expect fun EscapeHandler(callback: () -> Unit)
34+
expect fun EscapeHandler(callback: () -> Unit)

composeunstyled-tooltip/src/commonMain/kotlin/com/composeunstyled/KeyEventObserver.kt renamed to composeunstyled-escape-handler/src/commonMain/kotlin/com/composeunstyled/KeyEventObserver.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ import androidx.compose.ui.input.key.KeyEvent
3131
*
3232
*/
3333
@Composable
34-
expect fun KeyEventObserver(onEvent: (KeyEvent) -> Boolean)
34+
internal expect fun KeyEventObserver(onEvent: (KeyEvent) -> Boolean)

0 commit comments

Comments
 (0)