Created
October 15, 2021 17:15
-
-
Save Braayy/7335dc3b539c5c43abdade41d93b7840 to your computer and use it in GitHub Desktop.
A simple way to inject inline svg files at runtime on Compose For Web
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import kotlinx.browser.document | |
import kotlinx.browser.window | |
import org.jetbrains.compose.web.attributes.AttrsBuilder | |
import org.w3c.dom.* | |
import org.w3c.dom.svg.SVGElement | |
import kotlin.js.Date | |
enum class SvgIcon(val path: String) { | |
// Icons goes here | |
} | |
private object SvgUidHolder { | |
private val RANGE = 1..100_000 | |
private val usedUids = mutableListOf<Double>() | |
fun generateUid(): Double { | |
var uid = RANGE.random() * Date.now() | |
while (usedUids.contains(uid)) { | |
uid = RANGE.random() * Date.now() | |
} | |
usedUids.add(uid) | |
return uid | |
} | |
} | |
fun <T : Element> AttrsBuilder<T>.inlineIcon(icon: SvgIcon) { | |
ref { element -> | |
val uid = "inlinesvg-${icon.name.lowercase()}-${SvgUidHolder.generateUid()}" | |
injectInlineSvgInto(element, uid, icon.path) | |
onDispose { | |
element.getElementsByClassName(uid).asList() | |
.firstOrNull { element is SVGElement } | |
?.remove() | |
} | |
} | |
} | |
private fun injectInlineSvgInto( | |
parent: Element, | |
id: String, | |
path: String | |
) = window.fetch(path).then { it.text() }.then { svgText -> | |
val template = document.createElement("template") as HTMLTemplateElement | |
template.innerHTML = svgText | |
val svgElement = template.content.firstElementChild ?: throw IllegalArgumentException("$path svg content is not valid") | |
svgElement.classList.add(id) | |
parent.appendChild(svgElement) | |
svgElement | |
}.catch { | |
console.error("An error occurred while injecting inline svg: ${it.message}") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment