All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- GitLive bumped
3.0.0-alpha01→3.0.0-alpha02, Firebase BoM34.17.0→34.18.0. Kotlin (2.4.0), Compose MP (1.11.1), serialization and BCV are unchanged, so the SwiftPM iOS-linking model introduced in alpha01 is untouched. ⚠️ wasmJsmoved from the Measurement-Protocol tier to the native Firebase tier. Upstream PR #832 gives wasmJs full parity with the JS target, sowasmJsMainnow depends onfirebaseMainand runs the real Firebase JS SDK. Tier counts are now firebaseMain 11 / nonFirebaseMain 4.- Action required for wasmJs apps: a wasmJs app that previously supplied only
measurementProtocolmust now also supplyFirebaseConfig.web(applicationId,apiKey,projectId,authDomain) — wasmJs reads the samewebentry asjs. Skipping it means native init is silently skipped and analytics NoOps; there is no exception at config time. - Crashlytics is unchanged — upstream did not add
wasmjstofirebase-crashlytics, so wasmJs keeps theLoggingCrashReporterfallback for crash reporting.
- Action required for wasmJs apps: a wasmJs app that previously supplied only
- Fixed
FirebaseConfig.optionsForPlatform()never routed"wasmjs", so the tier move would have compiled cleanly and then failed at runtime on an uninitialized default app. Now"js", "wasmjs" -> web, with a regression test. - Regenerated
kotlin-js-store/wasm/yarn.lock(+680 lines of@firebase/*npm packages pulled in by the wasmJs binding). - Documentation corrected across
cmp-firebase/{README,DEVELOPMENT}.mdanddocs/firebase/*, including three pre-existing errors: iOS setup instructed consumers to use aPodfilethat GitLive 3.x no longer honors; a claim that alpha01 "droppediosX64/macosX64" (it did not); and a tier table that placed JVM underfirebaseMainand counted watchOS/wasmWasi as shipping targets (total is 15, not 21).
- Regenerated
cmp-share/api/jvm/cmp-share.api.ShareOptions.targetPackage(#161, 2026-08-27) added a fourth constructor parameter and shipped in v3.5.15 → v3.5.20 without the BCV dump being regenerated, leavingapiCheckred ondevelopmentthe whole time. - The signature change is a genuine binary break (the 3-arg constructor is replaced, not
overloaded), but
ShareOptionsis annotated@ExperimentalShareApi, so the break is sanctioned by that API tier. No source change was made — only the baseline now records what already shipped.
- Documentation site at https://mobilebytelabs.github.io/KmpToolkit/ —
mkdocs-material-powered, auto-published on push to
developmentvia.github/workflows/docs-publish.yml. Includes per-module landing pages for all 21 cmp-* modules + getting-started guide + cookbook with 12 task-oriented recipes across 4 topic areas (inter-app comms, network monitor, observability, storage). - Dokka 2.0 API reference bundled as
-javadoc.jarin every Maven Central artifact via the newio.github.mobilebytelabs.kmptoolkit.dokkaconvention plugin (build-logic/convention/) — IntelliJ / Android Studio hover-jump-to-symbol now shows full KDoc out of the box. - Cookbook recipe template at
docs/_partials/cookbook-recipe-template.mdfor community contributions. scripts/audit-kdoc-coverage.shto enumerate public symbols without KDoc — runs locally; not yet a hard gate (deferred to a follow-upkmp-toolkit-kdoc-backfillplan once the 286 missing-symbol backlog is worked through).
Plan: inter-app-comms-compose-completeness — 12-sub-plan epic on v0.3-alpha foundation.
Phase 0 — Spikes (SPIKE_FINDINGS_V0_4.md):
- S1.A Compose-MP target audit → UNCHANGED (CMP roadmap still at 9 targets per JetBrains)
- S1.B Win32 OPENFILENAMEW + IShellLinkW marshal → PROVISIONAL PASS
- S1.C tvOS Swift dispatch cinterop → PROVISIONAL PASS
- S1.D Gradle codegen approach → MANIFEST-JSON picked (zero KSP dep)
- S1.E Kover threshold calibration → per-module table (75-85%)
Phases 2-5 — ADR-09 closures:
- ADR-09 #1: tvOS Swift bridge probing wired (Swift class detected via ObjC runtime; full dispatch deferred to real-device CI)
- ADR-09 #2: watchOS
WCSession.transferFilereal impl for Image/File/Multi binary payloads - ADR-09 #3: mingw CF_DIB binary clipboard via Win32 cinterop (PROVISIONAL — needs Windows CI runtime verify)
- ADR-09 #4: JVM OS-detect with ProcessBuilder subprocess dispatch (macOS open / Linux xdg-open / Windows cmd start)
- ADR-09 #7/#8: cmp-intent-launcher Linux PickContact WONTFIX KDoc + mingw
GetOpenFileNameWreal impl - ADR-09 #11: cmp-app-intents watchOS/tvOS manifest writes + Swift bridge handoff + Linux XDG/.desktop + mingw APPDATA manifest
- ADR-09 #12:
generateShortcutsXml+generateSwiftIntentsGradle codegen tasks (MANIFEST-JSON approach)
Phases 6-7 — NEW Compose adapter modules:
cmp-share-compose—@Composable rememberShareLauncher()+ Material 3ShareSheet()+ShareButton()cmp-app-intents-compose—@Composable AppIntentsRegistration(config)(DisposableEffect lifecycle) +AppIntentsRegistry()Material 3 dev/debug LazyColumn UI
Phase 8 — cmp-intent-launcher-compose UX expansion:
@Composable IntentPickerDialog(contract, onResult, onDismiss)— Material 3 AlertDialog scaffold@Composable IntentPickerSheet(...)— Material 3 ModalBottomSheet variant- Material 3 + materialIconsExtended deps added
Phase 9 — ABI + coverage infrastructure:
binaryCompatibilityValidatorplugin applied to all 6 modules (3 core + 3 compose); baselines deferred to first Windows-CI green runkoverplugin applied to all 6 modules with per-S1.E thresholds (cinterop-heavy: 75-80%; pure-Kotlin compose: 85%)- Smoke commonTest cases authored for new compose modules
Phase 10 — Sample app:
samples/sample-inter-app-comms/composeAppadds dependencies on 3 compose adapter modules- New "Compose UX" tab demonstrates all opinionated Composables (ShareSheet, ShareButton, IntentPickerDialog, IntentPickerSheet, AppIntentsRegistration, AppIntentsRegistry)
iosApp/iosApp/AppIntents/CmpAppIntentBridge.swiftcommitted for end-to-end demo +Generated/dir scaffolded- NOTE: Linux/mingw native binary targets NOT added to sample composeApp (Compose Multiplatform doesn't support those targets per S1.A — would fail build); a future non-Compose
sample-inter-app-comms-nativeswould cover them
Phase 11 — Docs (shared-version-aware):
- NEW
docs/inter-app-comms/CAPABILITY_MATRIX.md— canonical 3-module × per-target × per-API support matrix - ADR-09 audit log updated per row (closed / WONTFIX / provisional)
@ExperimentalShareApi/@ExperimentalIntentLauncherApi/@ExperimentalAppIntentsApimarkers RETAINED in this toolkit release — marker drop is a future toolkit-release decision pending Windows CI verification of Win32 cinterop runtime correctness (S1.B PROVISIONAL needs runtime evidence before locking BCV baselines + dropping markers). All 6 IPC modules continue to ship with the sharedkmptoolkit.version(currently3.3.2; next bump to3.4.0lands this v0.4 epic).
Phase 13 — cmp-intent-launcher SystemIntents lifecycle-free entry points (post-Phase 11 follow-up):
SystemIntents.openAppSettings(): IntentResult— AndroidACTION_APPLICATION_DETAILS_SETTINGS, iOSUIApplicationOpenSettingsURLString, macOSNSWorkspace.open("x-apple.systempreferences:"), JVM OS-aware shell dispatch, Linux gnome-control-center→kcmshell5→xdg-open chain, Windowsstart ms-settings:appsfeatures. JS/wasmJs/tvOS/watchOS →Failed(UnsupportedPlatform).SystemIntents.createDocument(suggestedName, mimeType): IntentResult— Android invisible proxy Activity wrapsActivityResultContracts.CreateDocument(lifecycle-free), iOSUIDocumentPickerViewController(URLs:, inMode: ExportToService)withSystemIntentsDelegatePin, macOSNSSavePanel.runModal(), JVMJFileChooseron EDT viaDispatchers.IO, JS/wasmJswindow.showSaveFilePicker()viajs()/@JsFunwith state-discriminator callback, Linuxzenity --file-selection --save. mingw/tvOS/watchOS →Failed(UnsupportedPlatform)(Win32GetSaveFileNameWcinterop is a future task).- New auto-init infrastructure:
IntentLauncherInitProviderContentProvider +IntentLauncherContext(mirrorscmp-share/ShareInitProviderpattern).CreateDocumentProxyActivitydeclared in library manifest with translucent theme +excludeFromRecents. - Tests:
SystemIntentsContractTest(commonTest),SystemIntentsJvmTest(headless JVM),SystemIntentsAndroidUnitTest(no-init-provider failure-shape). - Unblocks pure-commonMain
IntentManagerconsumers (kmp-project-templateIntentManagerImpl) — no per-target source set needed foropenAppSettings/createDocument.
cmp-product-ticketsnow ships ajvm()target — Desktop Compose apps can consume the full ProductTickets DSL + UI + Supabase integration. Pure commonMain module (no platform-specific code), so the entire change was addingjvm()to the targets list. Transitive deps (Ktor, Supabase, Koin, kotlinx) were already JVM-ready.cmp-remote-configsame treatment —jvm()added, DynamicUiRenderer + RemoteConfigService + UiNode model all compile cleanly on JVM. Coil-compose, multiplatform-settings, supabase-postgrest all multiplatform-ready.- Motivation: the unified
samples/sample-toolkitcatalog app (also added in this release) needs every catalog library to support Desktop JVM. Previously these two were the only commonMain-only-but-JVM-missing libraries, blocking the desktop demo. - No API changes. No expect/actual added. No platform-specific source set introduced.
- New
samples/sample-toolkit/{composeApp,androidApp}showcases everycmp-*library in a single navigable Compose Multiplatform app. Home screen groups libraries by category (UI / Comms / Network / Lifecycle / Data / Backend); tap a card to drill into that library's demo screen. - Built with
androidx.navigation:navigation-compose-multiplatformv2.9.2 (already in the version catalog). - 15 demo screens covering: toast, bubble, clipboard, share, intent-launcher, app-intents, open-url, deep-link, network-monitor, in-app-update, pdf-generator, remote-config, firebase-analytics, product-tickets.
- Per-module samples (
sample-clipboard,sample-cmp-share,sample-inter-app-comms, etc.) remain alongside — sample-toolkit is the catalog, the per-module samples remain the focused references.
Toolkit version bumped 3.2.11 → 3.3.0. Two suite modules now ship 19 KMP targets each — matching the target matrix of cmp-deep-link / cmp-open-url / cmp-clipboard.
cmp-shareaddstvosX64/Arm64/SimulatorArm64,watchosX64/Arm32/Arm64/SimulatorArm64/DeviceArm64,linuxX64/Arm64,mingwX64(11 new targets, 19 total). Real implementations:- Linux: URL/file share via
xdg-opensubprocess (xdg-utilsdependency). Single-quote-escaped to prevent shell injection. - mingw (Windows): URL/file share via
cmd /c start. Double-quote-escaped. - tvOS:
UnsupportedPlatformfallback — Kotlin/Native bindings (as of Kotlin 2.3.10) don't exposeUIPasteboardfor tvOS even though the Objective-C API exists. - watchOS:
UnsupportedPlatformfallback — no share-sheet surface.
- Linux: URL/file share via
cmp-app-intentsadds same 11 targets (19 total). Tier-3 platforms get registry-only behavior —AppIntents.register()stores config inAppIntentsRuntime;invokeForTesting()works for dev/test on every platform. Swift bridgeCmpAppIntentBridge.swiftupdated with#if canImport(CoreSpotlight)guards so the same file compiles for iOS, macOS, tvOS, and watchOS — Spotlight indexing silently skips on tvOS/watchOS (no CoreSpotlight on those platforms).cmp-intent-launcherstays at 9 targets. Constraint discovered during Phase 10.A: the Compose Compiler Gradle plugin is module-level (not source-set-level) and requirescompose.runtimeon every target's classpath. ThecomposeMainintermediate source-set workaround fails because the compiler plugin runs before source-set resolution. Future v0.3 path: split intocmp-intent-launcher-core(non-Compose, 19 targets) +cmp-intent-launcher(current API, depends on -core). Documented inplan-layer/project-plans/mbs/kmp-toolkit/active/inter-app-comms-suite/10-platform-parity-v0-2.md.- wasmWasi remains excluded — server-side WASM has no DOM, no clipboard, no UI gesture surface (genuine technical impossibility).
- iOS picker contracts now route to native UIKit pickers.
ResultContracts.PickImagePickMultipleImages→PHPickerViewController(iOS 14+);PickDocument→UIDocumentPickerViewController;PickContact→CNContactPickerViewController. Suspend-coroutine bridges resume exactly once from the delegate callback (success / cancel / error); aDelegatePinsingleton holds strong refs while presentations are in flight to defend against ARC dropping the Kotlin/Native delegate shadow.
- Arbitrary actions still fall back to
onUnsupportedorIntentResult.Failed(UnsupportedPlatform). - Plan:
plan-layer/project-plans/mbs/kmp-toolkit/active/inter-app-comms-suite/09-per-module-samples.md§G-9.6 follow-up. - No public API changes — caller code that already used
ResultContracts.PickImagewith anonUnsupportedfallback now receives real picker results on iOS; the fallback is preserved for non-picker actions.
- Searchable intents are now indexed into iOS Spotlight + Siri Suggestions. The Swift
bridge
CmpAppIntentBridge.bootstrap(callbackResolver:)reads the manifest written by Kotlin'sAppIntents.register(config), pushes everysearchable: trueentry intoCSSearchableIndex.defaultSearchableIndex()with title + contentDescription, and exposeshandleContinue(_:)to route Spotlight taps back into the Kotlin DSL viaCmpAppIntentsCallback.shared.handler. - Activity prefix
com.mobilebytelabs.kmptoolkit.appintents.<id>is the user-activity type to declare in your Info.plistNSUserActivityTypesarray. - Real Kotlin↔Swift callback wiring replaces the placeholder
print()from v0.1. The bridge uses KVC +NSSelectorFromString("invoke::")so it stays framework-alias agnostic (works whether your Kotlin/Native framework is published askmptoolkit,shared, or any custom name). - macOS 10.13+ also benefits —
CoreSpotlightis available there. - Plan:
plan-layer/project-plans/mbs/kmp-toolkit/active/inter-app-comms-suite/09-per-module-samples.md§Resolved deferred items. - Migration: existing consumers should replace
CmpAppIntentBridge.shared.loadManifest()at app launch withCmpAppIntentBridge.shared.bootstrap { CmpAppIntentsCallback.shared }.
org.gradle.jvmargsbumped to-Xmx4096M(was 2048M). The lower heap was OOMing wasmJs compilation when 3+ new sample modules with Compose were added to the workspace. Local developer machines and CI both benefit; no downstream changes required.compose.desktop.packaging.checkJdkVendor=falseadded togradle.propertiesto permitcreateDistributableruns on Homebrew JDKs (per JetBrains/compose-multiplatform#3107). CI release pipelines are unaffected — they use vendor-pinned Corretto/Temurin where the flag is a no-op.
- New module
cmp-pdf-generator— cross-platform PDF generation library. Coordinates:io.github.mobilebytelabs:cmp-pdf-generator(ships at the sharedkmptoolkit.version). - Input modes: HTML string, Markdown (via
MarkdownPdfAdapter), DSL (pdf { … }). Composable snapshot + image-to-PDF deferred to a future release. - Output destinations: File, ByteArray, platform URI, Share, Print, Save.
- Page config: A3/A4/A5/B5/LETTER/LEGAL/TABLOID/STATEMENT + custom size + portrait/landscape + per-edge margins + optional per-page header/footer/page-numbers.
- Branding: injectable
PdfBranding(logo, poweredByText, theme, dateFormatter, watermark). De-brandedHtmlTemplateGeneratorbase class. - Pre-built templates:
InvoiceTemplate,ReportTemplate,ReceiptTemplate,StatementTemplate,LetterTemplate. - Error model: sealed
PdfErrorhierarchy + cancellation +Flow<PdfProgressEvent>. - Platforms: Android, iOS (14+), macOS (11+), JVM, JS (browser+nodejs),
wasmJs (HTML route only — DSL/byte route deferred pending pdf-lib wasmJs interop).
Not targeted: tvOS, watchOS, Linux native, mingwX64, wasmWasi —
kotlinx-htmlandorg.intellij.markdowndon't publish artifacts there. - Marker: all public symbols
@ExperimentalPdfGeneratorApiuntil v1.0. - PLAN:
plan-layer/project-plans/mbs/kmp-toolkit/active/cmp-pdf-generator/(epic, 12 sub-plans, 266 tasks).
- iOS / macOS
AppHintparity (G6 fix) —openWithApp(url, AppHint.{EMAIL/PHONE/SMS/MAPS})on Apple platforms now rewrites the URL to the scheme-appropriate form (mailto:,tel:,sms:,maps:/geo:) BEFORE callingUIApplication.openURL/NSWorkspace.openURL. Previously the hint was silently ignored —AppHint.EMAIL + bare HTTPSwould open Safari instead of Mail.app. Incompatible (url, hint) combinations now returnOpenUrlResult.Error(message)with a clear hint about the required URL scheme.AppHint.Custom(packageName)is now documented as Android-only; on iOS / macOS / JVM / JS / wasmJs it silently falls back toAppHint.DEFAULTbehaviour (no behaviour change vs the previous silent fallback — only KDoc clarification).- Pure-logic
transformUrl()helper added in commonMain (internal); 20+ unit-test cases cover the rewrite matrix. - Plan:
plan-layer/project-plans/mbs/kmp-toolkit/active/inter-app-comms-suite/03-open-url-g6-fix.md - No public API changes — BCV baseline unaffected; consumer code requires no migration.
- Removed dependency on
cmp-product-tickets.cmp-remote-configis now standalone. No transitive Maven pull, no shared config object, no cross-module imports. - Public API reduced to a single Koin DSL extension:
fun Module.remoteConfig(block). Drops the previous publicval remoteConfigModule+object RemoteConfigConfig. RemoteConfigConfig(public mutable singleton withifEmpty { ProductTicketsConfig.x }fallbacks) deleted. Replaced by an internalRemoteConfigSettingsdata class populated via the DSL builder.- Dropped
productTypeparameter. Per-project Supabase model (mirrors cmp-product-tickets v3.0.0 — each consumer app has its own Supabase project, so theproduct_typefilter column is meaningless on the client). Removed from:RemoteConfigServicector,getActiveConfigs()filter,get_device_impressions/record_config_impression/dismiss_configRPC parameters (p_product_type),RemoteConfigdata class (@SerialName("product_type")field),RemoteConfigBuilderDSL,RemoteConfigSettings.- Server follow-up: the
product_remote_config.product_typecolumn andp_product_typeRPC arguments can be dropped in a separate migration; until then they remain ignored (ignoreUnknownKeys = trueon the JSON deserializer).
- Server follow-up: the
ActionTypechanged fromenum classto@JvmInline value class. Built-in constants (NONE/URL/DEEPLINK/STORE/DISMISS) preserved as companion vals; consumer apps can extend with their own:object RemoteActions { val OPEN_DOWNLOADS = ActionType("open_downloads") }. New built-in:PREMIUM.ActionType.from(value)removed — construct directly:ActionType("my_type").- New extensible action dispatcher. Register handlers in the DSL via
action("type") { value, ctx -> … }. Handlers fire whenRemoteConfigHostis called without an explicitonActionparameter; the explicitonActionescape hatch is preserved.
// Before
ProductTicketsConfig.init(supabaseUrl, supabaseAnonKey, boardType = "your_app")
startKoin { modules(productTicketsModule, remoteConfigModule) }
// After (one block inside any existing Koin module)
val networkModule = module {
remoteConfig {
supabaseUrl = "https://YOUR_PROJECT.supabase.co"
supabaseKey = "YOUR_ANON_KEY"
action(ActionType.PREMIUM) { _, _ -> AppNavigator.navigateTo("paywall") }
action("open_downloads") { v, _ -> AppNavigator.navigateTo("downloads/${v.orEmpty()}") }
}
// … your other bindings …
}
startKoin { modules(networkModule, /* other modules */) } // remoteConfigModule no longer exists-
New Module: kmp-open-url (
io.github.mobilebytelabs:kmp-open-url:3.2.1)- Cross-platform URL opening for all 14 KMP targets
openUrl(url)— open with default platform handler, never throwsopenInBrowser(url)— force system browser, bypasses app-association rulesopenWithApp(url, AppHint)— open with preferred app category, returnsOpenUrlResultcanOpen(url)— check URL handleability without openingAppHintsealed class: DEFAULT, BROWSER, EMAIL, MAPS, PHONE, SMS, Custom(packageName)OpenUrlResultsealed class: Success, NoHandler, Error(message)- Android:
Intent.ACTION_VIEW+ ContentProvider auto-init (zero setup) - iOS/macOS:
UIApplication.openURL/NSWorkspace.openURLvia sharedappleMain - tvOS/watchOS: graceful
NoHandler— no crash - JVM Desktop:
Desktop.getDesktop().browse()+xdg-openheadless fallback - JS Browser:
window.open(url, "_blank") - wasmJs:
window.openvia@JsFuninterop - Linux Native:
xdg-openviaplatform.posix.system - Windows Native:
ShellExecuteWvia Win32 API - wasmWasi: deliberate no-op (no display concept)
-
New Module: kmp-clipboard (
io.github.mobilebytelabs:kmp-clipboard:0.1.0)- Extracted clipboard functionality into standalone module
- ClipboardObserver for monitoring clipboard changes with app foreground detection
- Platform-specific implementations: Android (ClipboardManager + ProcessLifecycleOwner), iOS (UIPasteboard), macOS (NSPasteboard), JVM (AWT FlavorListener), JS (navigator.clipboard), Linux (xclip/xsel), Windows (Win32 API)
- All 20+ platform targets supported
-
New Module: kmp-toast (
io.github.mobilebytelabs:kmp-toast:0.1.0)- Pure Compose Multiplatform toast/snackbar notifications
- Duration options: SHORT (2s), MEDIUM (3.5s), LONG (5s), INDEFINITE
- Position options: TOP, CENTER, BOTTOM
- Style options: DEFAULT, SUCCESS, ERROR, WARNING, INFO
- Action button support and swipe-to-dismiss
-
New Module: kmp-in-app-update (
io.github.mobilebytelabs:kmp-in-app-update:0.5.0)- Extracted from cmp-library into dedicated module
- Check for app updates with GitHub Releases, Supabase, or custom backends
- Platform-specific implementations for Play Store, App Store, Mac App Store
- Update types: NONE, FLEXIBLE, IMMEDIATE
-
Template Module: cmp-library (
io.github.mobilebytelabs:kmp-template:1.0.0-template)- Converted to template/reference module for creating new libraries
- Includes TEMPLATE_README.md with step-by-step instructions
- Sample expect/actual pattern with Greeting.kt and Platform.kt
-
Sample Apps
sample-clipboard: Clipboard + Observer + Toast integration demosample-in-app-update: In-App Update demo with GitHub Releases
- Modular Architecture: KMP Toolkit now uses a modular architecture
- Each feature is a standalone library module
- Consumers can import only the features they need
- GitHub Actions auto-discovers and publishes all cmp-* modules
- Added
MODULE_STRUCTURE.mddocumenting the modular architecture pattern - Updated
README.mdwith new installation instructions for individual modules - Added
TEMPLATE_README.mdfor creating new library modules
- Initial release as standalone module (extracted from cmp-library)
- Cross-platform in-app update checking:
AppUpdate.checkForUpdate(config)- Check for available updatesAppUpdateConfig.builder()- Configure update sourcesGitHubResolver- Check updates via GitHub ReleasesSupabaseResolver- Check updates via Supabase backend
| Platform | Native Store | Custom Resolver |
|---|---|---|
| Android | ✅ Play Store | ✅ |
| iOS | ✅ App Store | ✅ |
| macOS | ✅ Mac App Store | ✅ |
| JVM | ❌ | ✅ |
| Linux | ❌ | ✅ |
| Windows | ❌ | ✅ |
| JS | ❌ | ❌ |
| Wasm | ❌ | ❌ |
- Initial release as pure Compose Multiplatform module
- Toast/Snackbar notifications:
ToastHost- Container composable for toastsrememberToastHostState()- State managementshowToast()- Display toast with customization
- Duration: SHORT (2s), MEDIUM (3.5s), LONG (5s), INDEFINITE
- Position: TOP, CENTER, BOTTOM
- Style: DEFAULT, SUCCESS, ERROR, WARNING, INFO
- Action button support
- Swipe-to-dismiss gesture
Works on all Compose Multiplatform targets (Android, iOS, macOS, JVM, Web)
- Initial release as standalone module
- Cross-platform clipboard utilities:
copyToClipboard(text: String): Boolean- Copy text to clipboardgetFromClipboard(): String?- Read text from clipboardhasClipboardText(): Boolean- Check if clipboard has textclearClipboard()- Clear clipboard contents
| Platform | Copy | Read | Notes |
|---|---|---|---|
| Android | ✅ | ✅ | Auto-initialized via ContentProvider |
| iOS | ✅ | ✅ | Uses UIPasteboard |
| macOS | ✅ | ✅ | Uses NSPasteboard |
| JVM | ✅ | ✅ | Uses AWT Toolkit |
| Linux | ✅ | ✅ | Requires xclip or xsel |
| Windows | ✅ | ✅ | Uses Win32 API |
| JS | ✅ | ❌ | Async API, write-only for sync |
| Wasm JS | ❌ | ❌ | Complex JS interop required |
| Wasm WASI | ❌ | ❌ | No clipboard in WASI runtime |
| tvOS | ❌ | ❌ | No pasteboard support |
| watchOS | ❌ | ❌ | No pasteboard support |
- Converted from production library to template/reference module
- All production code moved to dedicated modules:
- Clipboard →
kmp-clipboard - App Update →
kmp-in-app-update - Toast →
kmp-toast
- Clipboard →
- Reference implementation for creating new KMP library modules
- Sample expect/actual pattern with
Greeting.ktandPlatform.kt - Step-by-step instructions in
TEMPLATE_README.md
- App Update functionality (now in kmp-in-app-update)
- Initial release with Clipboard and App Update features combined
The monolithic kmp-toolkit has been split into focused, independent modules. Choose only the modules you need:
// build.gradle.kts
kotlin {
sourceSets {
commonMain.dependencies {
// Before (all features bundled)
// implementation("io.github.mobilebytelabs:kmp-toolkit:0.5.0")
// After (import only what you need)
implementation("io.github.mobilebytelabs:kmp-clipboard:0.1.0") // Clipboard utilities
implementation("io.github.mobilebytelabs:kmp-toast:0.1.0") // Toast/Snackbar UI
implementation("io.github.mobilebytelabs:kmp-in-app-update:0.5.0") // App update checking
}
}
}| Feature | Old Import | New Import |
|---|---|---|
| Clipboard | com.mobilebytelabs.kmptoolkit.* |
com.mobilebytelabs.kmptoolkit.clipboard.* |
| Toast | N/A (new) | com.mobilebytelabs.kmptoolkit.toast.* |
| App Update | com.mobilebytelabs.kmptoolkit.appupdate.* |
com.mobilebytelabs.kmptoolkit.appupdate.* (unchanged) |