Reputation: 497
I have a Compose Web app. How can I render Markdown on it?
Upvotes: 1
Views: 689
Reputation: 497
I found a fairly simple solution, by using the md-block library.
First we need to import the md-block script. We can either add it as an npm dependency, or simply load the module from url, like so.
<!-- Put this in your index.html -->
<script type="module" src="https://md-block.verou.me/md-block.js"></script>
And then in Kotlin:
// In your view html dsl:
var mdText: String? by mutableStateOf(null)
Button(attrs = {
onClick {
scope.launch {
mdText = null // Reset value for md-block re-rendering
mdText = viewModel.fetchContent()
}
}
}) {
Text("Fetch data!")
}
mdText?.let {
MarkDown(it)
}
// In some shared file:
@Composable
fun MarkDown(
mdText: String,
attrs: AttrBuilderContext<HTMLElement>? = null,
) {
TagElement(
elementBuilder = {
document.createElement("md-block").cloneNode() as HTMLElement
},
applyAttrs = attrs,
) {
Text(mdText)
}
}
Note that md-block is made so that it won't re-render on recomposition, even though the state value changes (see documentation for details). That is why we must nullify mdText before setting a new value, so that the <md-block>
is completely removed and re-added.
Is there a better way?
Upvotes: 0