colintheshots / MarkdownTwain

A Jetpack Compose UI library for editing Markdown content on Android, based on Markwon
Apache License 2.0
125 stars 5 forks source link

`MarkdownText` conflicts with `Modifier.clickable #7

Open jber18 opened 6 days ago

jber18 commented 6 days ago

Description:
When using the MarkdownText composable from the library, it renders the markdown content using an AndroidView. However, I encountered an issue where adding a Modifier.clickable to the MarkdownText or any of its parent containers does not register click events properly. This behavior creates conflicts when I try to wrap the MarkdownText with clickable elements for interaction.


Steps to Reproduce:

  1. Use MarkdownText in a Jetpack Compose component.
  2. Try wrapping it inside a Box or Row with a Modifier.clickable to detect taps.
  3. Observe that the click events are not registered, and the onClick callback is never triggered.
@Composable
fun TestMessage() {
    Box(
        modifier = Modifier
            .clickable { // This never gets called
                println("Clicked!")
            }
            .padding(16.dp)
    ) {
        MarkdownText(
            markdown = "This is **markdown** text!",
            modifier = Modifier.fillMaxWidth()
        )
    }
}

Expected Behavior:


Actual Behavior:


Possible Cause:

The MarkdownText composable uses AndroidView under the hood to render markdown content via the Markwon library. Since AndroidView bridges the Android View system with Jetpack Compose, it consumes touch events internally, preventing them from propagating properly to the outer composables.

This is a known issue when mixing AndroidView with Compose gesture handlers, as the Android view hierarchy does not seamlessly cooperate with the Compose UI system.


Workaround Attempts:

I tried a few potential solutions, but none resolved the issue:

  1. Adding a clickable Modifier to the parent Box: No success; the click is never registered.
  2. Adding a transparent overlay for gesture detection: This blocked the visual content, which is not ideal for UI.
  3. Using zIndex adjustments: Had no effect, as AndroidView still intercepts the gestures.

Suggested Solutions:

  1. Expose a onClick callback directly in the MarkdownText composable. This way, the click events can be handled internally within the AndroidView.

    Example API:

    @Composable
    fun MarkdownText(
       markdown: String,
       modifier: Modifier = Modifier,
       onClick: () -> Unit = {}
    ) { ... }
  2. Alternatively, provide guidance on how to integrate MarkdownText with Compose's clickable modifier or gesture detection.


Environment:


colintheshots commented 4 days ago

I deliberately didn't want clicks to get intercepted at the top-level, so URLs would be clickable with their own handlers. One usually wants clicks to be handled at the lowest-level.

What level are you expecting to be clickable? The TextView? I assume you wouldn't want to also handle clicks on URLs or anything linkified in the same click handler?