A little teaser - How would like such DSL? ```// D...
# web-mpp
t
A little teaser - How would like such DSL?
Copy code
// Define some hooks. Maybe I'll bulk generate those for all tags later.
// Using Element API
fun CTagBuilder<OPTION>.onSelect(callback : (Event) -> Unit) {
    attach<HTMLSelectElement> { element -> HTMLSelectElement
        //element.onselect = callback
        //or
        element.addEventListener("onselect", callback)
    }
}

// Using TagConsumer API
fun TagConsumer<*>.onSelect(tag : OPTION /** No multiple receivers yet : ( */, callback : (org.w3c.dom.events.Event) -> Unit) {
    onTagEvent(tag, "onselect", callback)
}

// This should be global in JS / request scoped on server
val flow: Flow = Flow()

// Define mutable and observable value
val selectedStyle: Property<Style> = flow.Property(defaultStyle)


// Define some content
val styleSelectionBlock: CBlock = {
    tag(::SELECT) {
        for(style in availableStyles) {
            tag(::OPTION) {
                onSelect {
                    flow {
                        selectedStyle.value = style
                    }
                }
            }
        }
    }
}

fun TagConsumer<*>.styleSelectionBlock2() = {
    select {
        for(style in availableStyles) {
            option {
                onSelect(this) {
                    selectedStyle.value = style
                }
            }
        }
    }
}

val styleDemoBlock: CBlock = {
    tag(::DIV) {
        bind(DIV::classes, selectedStyle.map { setOf(it.className) })

        dynamic(selectedStyle) {
            "This text is shown with the style \"${it.name}\""
        }
    }
}

val styleSelectWithPreview : CBlock = {
    styleSelectionBlock()
//        styleSelectionBlock2() // That works too. kotlinx-html API is supported.
    +styleDemoBlock
}
Than
Copy code
// This is in commonMain, you can render to text on client too.
fun renderOnServer(out : Appendable) {
    val context = RootContext(emptyMap())
    context.render(styleDemoBlock, out)
}
And
Copy code
val rootContext by lazy { RootContext(emptyMap())}

fun hydrateOnClient() {
    // We already rendered on server. Now we're just binding model/listeners to the DOM
    rootContext.hydrate(styleSelectWithPreview, rootElement)
}
// or
fun renderOnClient() {
    rootContext.render(styleSelectWithPreview, rootElement)
}