With fritz2, you can easily use WebComponents in any HTML-context. Some of the following code-snippets are not runnable on their own. Please find the complete example here.
Before you can use a custom HTML element, you have to add the component to your site's scripts.
One way is adding a <script>
tag which points to the component in your HTML file:
<script type="module" src="https://unpkg.com/@mat3e-ux/stars"></script>
then you can use the custom()
tag to render the imported webcomponent:
render {
custom("m3-stars") {
attr("max", "5")
attr("current", "3.5")
}
}
If the component you want to use is published on npm, you can add it as a dependency
in your gradle.build.kts
:
dependencies {
implementation(npm("@mat3e-ux/stars", "0.2.5"))
}
and import it in your Kotlin-Code:
@JsNonModule
@JsModule("@mat3e-ux/stars")
external object Stars
Please see the official documentation for more details on this.
For obvious reasons we cannot provide typesafe attributes for custom elements,
but you can implement an HtmlTag
and provide an extension function for RenderContext
:
class M3Stars(job: Job, scope: Scope) : HtmlTag<HTMLElement>("m3-stars", job = job, scope = scope) {
fun max(value: Flow<Int>) = attr("max", value.asString())
fun max(value: Int) = attr("max", value)
fun current(value: Flow<Float>) = attr("current", value.asString())
fun current(value: Float) = attr("current", value)
}
fun RenderContext.m3Stars(content: M3Stars.() -> Unit): M3Stars = register(M3Stars(job, scope), content)
To build a WebComponent with fritz2, two steps are necessary. First, implement your WebComponent class:
object WeatherCard : WebComponent<HTMLDivElement>() {
private val city: Flow<String> = attributeChanges("city")
override fun RenderContext.init(element: HTMLElement, shadowRoot: ShadowRoot): HtmlTag<HTMLDivElement> =
div("weather-card") {
h2 { city.renderText() }
// ...
}
}
Also add an observed attribute named city
to be set by the user of this component. Next, register the component and
add the observed city
to the registration.
fun main() {
registerWebComponent("weather-card", WeatherCard, "city")
}
To react to the lifecycle of your component, you can override the according methods from the specification.
Packaging (i.e. as an npm-package) and publishing is out of scope of this documentation.
To see it in action, please have a look at our webcomponents example.