Arjan van Wieringen

    Arjan van Wieringen

    4 months ago
    Hello, is their a reason the experimental SVG api only has composables in the
    ElementScope<SVGElement>
    context? The normal HTML elements don't do that. It makes it impossible (due to the lack of JS support for now for multiple context receivers) to write context-aware composables for SVG elements.
    o

    Oleksandr Karpovich [JB]

    4 months ago
    It was made so to avoid an issue when SVG composable would be invoked within html:
    <div><polygon.../></div>
    Perhaps, something like this can help:
    class MyElementsScope(scope: ElementScope<SVGElement>) : ElementScope<SVGElement> by scope
    
    @OptIn(ExperimentalComposeWebSvgApi::class)
    @Composable
    fun MyElementsScope.MyPolyline() {
        Polyline(1, 2, 3, 4, 5, 6, 7,  8, 9, 10)
    }
    
    @OptIn(ExperimentalComposeWebSvgApi::class)
    @Composable
    fun UseMyElementsScope() {
        Svg { 
            with(MyElementsScope(this)) {
                MyPolyline()
            }
        }
    }
    or scope instance even might be remembered:
    @Composable
    fun UseMyElementsScope() {
        Svg {
            val myElementsScope = remember { MyElementsScope(this) }
            with(myElementsScope) {
                MyPolyline()
            }
        }
    }
    Arjan van Wieringen

    Arjan van Wieringen

    4 months ago
    Thanks that looks like a good workaround. I understand the reason behind it, but it removes a lot of language freedom. HTML 'allows' to put SVG elements inside a DIV but it just wont show anything and it'll probably throw a console error. I don't think this is something Compose-web should enforce. It isn't the responsiblity of compose and this enforcement removes a lot of flexiblity. You could also argue, for instance, for disallowing
    thead
    elements outside any
    table
    . But we have all the freedom to do that 😉 . Or we can add
    option
    outside of
    select
    elements.