Has anyone had any success with making web-compone...
# javascript
a
Has anyone had any success with making web-components via Kotlin/JS? I've stumbled upon the following sources: https://discuss.kotlinlang.org/t/creating-a-custom-element-webcomponent/3988/14 https://github.com/semantic-logic-tools/kotlin-web-component But so far, to no avail. Every code I tried I get stranger and stranger errors. Does anyone have any working examples?
a
We had a prototype inside team with the
lit
library. I will try to open-source it until the end of this year.
t
We have fixed
HTMLElement
in Kotlin Wrappers with 0 abstract methods. Single known problem - registration in
customElementRegistry
, which is sideeffect, which must be applied, only if component used.
a
@turansky thanks, these Kotlin wrappers are additional to the Kotlin Js browser api right? The problem you mention with the registry, how is this an issue? I can apply it like any normal function right?
t
Kotlin wrappers are additional to the Kotlin Js browser api right?
It's full replacemant. To avoid redundant imports you can use this flag.
I can apply it like any normal function right?
You can call registration in
main
function. As result - tree shaking won't work
๐Ÿ‘ 1
๐Ÿ‘๐Ÿพ 1
a
Hmm, I am getting errors:
Copy code
@JsExport
class HelloWorldElement : HTMLElement() {
    init {
        innerHTML = "Hello World"
    }
}

fun main() {
    window.customElements.define("hello-world", { HelloWorldElement() })
}
And the error is:
Copy code
Uncaught TypeError: Failed to construct 'HTMLElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function.
t
a
Ah yes, I only had esModules enabled...
Too bad. First of all it completely breaks when I have compose plugin enabled, after disabling that one I get:
Copy code
Uncaught TypeError: Illegal constructor
    at createExternalThis (coreRuntime.kt:242:24)
    at HelloWorldElement.new_nl_avwie_webcomponent_HelloWorldElement_vllg41_k$ (compose-web-component.js:15:19)
    at new main$lambda (App.kt:14:51)
createExternalThis @ coreRuntime.kt:242
new_nl_avwie_webcomponent_HelloWorldElement_vllg41_k$ @ compose-web-component.js:15
main$lambda @ App.kt:14
I was hoping to have a Compose HTML working behind a shadow-dom, but I think that will be quite difficult.
t
What if you will replace
init
with constructor body?
a
No, nothing changes. Even if I remove the init and don't do any constructor actions at all
Thanks for you help by the way. I really appreciate it ๐Ÿ™‚
t
I see
You have invalid registration
Expected:
Copy code
customElements.define("hello-world", HelloWorldElement::class.js)
a
That doesn't work, it should be
Copy code
class HelloWorldElement : HTMLElement() {
}

fun main() {
    window.customElements.define("hello-world", { HelloWorldElement::class.js })
}
However, then i get
Copy code
Uncaught TypeError: Failed to construct 'CustomElement': The result must implement HTMLElement interface
๐Ÿ˜„
t
It's not what I wrote
Don't add lambda please
Please use Kotlin Wrappers with strict signatures
a
There are differences between the kotlin-wrapper
customElements
and the normal one. However, this wont work:
Copy code
```import web.html.HTMLElement
import web.html.customElements


class HelloWorldElement : HTMLElement() {
}

fun main() {
    customElements.define("hello-world", HelloWorldElement::class.js)
}
Which results in a compiler error:
Copy code
Type mismatch.
Required:
CustomElementConstructor /* = JsClass<HTMLElement> */
Found:
JsClass<HelloWorldElement>
t
In
kotlin-browser
you will find strict declarations for
CustomElementRegistry
Just for test
Copy code
customElements.define("hello-world", HelloWorldElement::class.js.asDynamic())
a
It doesn't crash anymore, so that's positive.
However, nothing happens. The
connectedCallback
etc handlers are missing from the wrappers. Am I correct?
Works:
Copy code
@JsExport
class HelloWorldElement : HTMLElement() {

    @JsName("connectedCallback")
    fun connectedCallback() {
        innerHTML = "<h1>Hello World</h1>"
    }
}

fun main() {
    customElements.define("hello-world", HelloWorldElement::class.js.asDynamic())
}
Coolio
t
a
Wow, that's fast
Too bad Compose Compiler doesn't work with ES classes... yet
t
However, nothing happens. The
connectedCallback
etc handlers are missing from the wrappers. Am I correct?
In TypeScrript it's also isn't declared ๐Ÿ™‚
a
Makes sense. 'Magic' methods ๐Ÿ˜‰
t
Draft - declare it as optional property ๐Ÿ˜ž
More elegant - additional interfaces
a
Yeah. Well at least I am happy I got something on my screen. Working around the interfaces isn't a problem. But Compose compiler is blocking for me now sadly. https://youtrack.jetbrains.com/issue/KT-63991/Jetbrains-Compose-compiler-failes-on-web-project-with-useEsClasses-or-useEsModules-enabled
t
Like
HasConnectedCallback
a
Thanks a lot for your help. Mainly they were config issues on my side.
๐Ÿ˜‰ 1
t
Wrappers
pre.654
release.
asDynamic()
call can be removed.