This question is about a Kotlin JS project which uses the Kotlin Frontend Plugin.
I want to use some UI components from the Vaadin Components library.
I have two questions about this:
(1) What would be the best way to include web components in Kotlin JS
=> for my complete code, see the link to the source below. In summary the relevant details are:
build.gradle.kts
kotlinFrontend {
npm {
dependency("@vaadin/vaadin-grid")
}
}
vaadin.grid.Imports.kt
@file:JsModule("@vaadin/vaadin-grid")
@file:JsNonModule
package vaadin.grid
external class GridElement {
companion object
}
Why the companion object
? I need it for the workaround (see below).
foo.kt
fun main() {
document.getElementById("container")!!.append {
vaadin_grid {
attributes["id"] = "grid"
}
}
initUI()
}
fun initUI() {
// Force the side-effects of the vaadin modules. Is there a better way?
console.log(GridElement)
val grid = document.querySelector("#grid") /* ?? as GridElement ?? */
}
The console.log
is the ugly workaround trick I want to avoid. If I don't do anything with GridElement then it's just not included in my bundle.
The vaadin_grid
DSL is defined as a custom kotlinx.html tag which is unrelated code.
(2) I want to keep my code as typed as possible to avoid asDynamic
but when I cast the HTMLElement
to a Vaadin Element I get ClassCastExceptions (because GridElement
is undefined
).
For example I want to write something like this:
val grid : GridElement = document.querySelector("#grid") as GridElement
grid.items = ... // vs grid.asDynamic().items which does work
Here is how I define the external GridElement
vaadin/button/Imports.kt
@file:JsModule("@vaadin/vaadin-grid")
@file:JsNonModule
package vaadin.grid
import org.w3c.dom.HTMLElement
abstract external class GridElement : HTMLElement {
var items: Array<*> = definedExternally
}
build/node_modules/@vaadin/vaadin-grid/src/vaadin-grid.js
...
customElements.define(GridElement.is, GridElement);
export { GridElement };
To run:
From the root of the git repo:
./gradlew 05-kt-frontend-vaadin:build && open 05-kt-frontend-vaadin/frontend.html