From e175dd47c05723457010ccb580fe463f0c4c2cf9 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Fri, 4 Nov 2022 14:56:40 -0500 Subject: [PATCH] make components both simpler and more powerful (#370) --- api/kweb-core.api | 10 ++++++--- src/main/kotlin/kweb/state/render.kt | 28 ++++++++++++++++++++----- src/test/kotlin/kweb/docs/components.kt | 12 +++++------ 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/api/kweb-core.api b/api/kweb-core.api index bf0b3cd24e..9ff3fa214d 100644 --- a/api/kweb-core.api +++ b/api/kweb-core.api @@ -1724,6 +1724,10 @@ public final class kweb/routing/RouteReceiver { public final fun path (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)V } +public abstract interface class kweb/state/AdvancedComponent { + public abstract fun render (Lkweb/ElementCreator;)Ljava/lang/Object; +} + public final class kweb/state/CloseReason { public fun (Ljava/lang/String;Ljava/lang/Throwable;)V public synthetic fun (Ljava/lang/String;Ljava/lang/Throwable;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -1738,8 +1742,8 @@ public final class kweb/state/CloseReason { public fun toString ()Ljava/lang/String; } -public abstract interface class kweb/state/Component { - public abstract fun render (Lkweb/ElementCreator;)Ljava/lang/Object; +public abstract interface class kweb/state/Component : kweb/state/AdvancedComponent { + public abstract fun render (Lkweb/ElementCreator;)V } public class kweb/state/KVal : java/lang/AutoCloseable { @@ -1861,7 +1865,7 @@ public final class kweb/state/RenderHandle { public final class kweb/state/RenderKt { public static final fun closeOnElementCreatorCleanup (Lkweb/ElementCreator;Lkweb/state/KVal;)V - public static final fun render (Lkweb/ElementCreator;Lkweb/state/Component;)Ljava/lang/Object; + public static final fun render (Lkweb/ElementCreator;Lkweb/state/AdvancedComponent;)Ljava/lang/Object; public static final fun render (Lkweb/ElementCreator;Lkweb/state/KVal;Lkotlin/jvm/functions/Function2;)Lkweb/state/RenderFragment; } diff --git a/src/main/kotlin/kweb/state/render.kt b/src/main/kotlin/kweb/state/render.kt index ce3ca62cbd..704586b561 100755 --- a/src/main/kotlin/kweb/state/render.kt +++ b/src/main/kotlin/kweb/state/render.kt @@ -128,24 +128,42 @@ fun ElementCreator<*>.closeOnElementCreatorCleanup(kv: KVal<*>) { * Render the value of a [KVar] into DOM elements, and automatically re-render those * elements whenever the value changes. */ -fun ElementCreator<*>.render(component: Component) : R { +fun ElementCreator.render( + component: AdvancedComponent +) : RETURN_TYPE { return component.render(this) } // ANCHOR: component_definition /** - * [Component]s can be rendered into DOM elements by calling [Component.render]. + * [AdvancedComponent]s can be rendered into DOM elements by calling [AdvancedComponent.render]. + * + * Unlike [Component], [AdvancedComponent]s allows the parent element type to be configured, and a return + * type to be specified. */ -interface Component { +interface AdvancedComponent { /** * Render this [Component] into DOM elements, returning an arbitrary - * value of type [R]. + * value of type [RETURN_TYPE]. */ - fun render(elementCreator: ElementCreator<*>) : R + fun render(elementCreator: ElementCreator) : RETURN_TYPE } // ANCHOR_END: component_definition +/** + * [Component]s can be rendered into DOM elements by calling [Component.render]. + * + * For more flexibility, see [AdvancedComponent]. + */ +interface Component : AdvancedComponent { + + /** + * Render this [Component] into DOM elements + */ + override fun render(elementCreator: ElementCreator) +} + class RenderFragment(val startId: String, val endId: String) { private val deletionListeners = ArrayList<() -> Unit>() diff --git a/src/test/kotlin/kweb/docs/components.kt b/src/test/kotlin/kweb/docs/components.kt index 0d917deb52..2e2d16b5d1 100644 --- a/src/test/kotlin/kweb/docs/components.kt +++ b/src/test/kotlin/kweb/docs/components.kt @@ -13,8 +13,8 @@ import kweb.util.json class SimpleComponent( val prompt: String = "Enter Your Name", val name: KVar -) : Component { - override fun render(elementCreator: ElementCreator<*>) { +) : Component { + override fun render(elementCreator: ElementCreator) { with(elementCreator) { div { h1().text(prompt) @@ -48,11 +48,11 @@ class BulmaInput( val state: KVal? = null, val disabled: KVal? = null, val value: KVar -) : Component { +) : Component { - override fun render(elementCreator: ElementCreator<*>) : InputElement { + override fun render(elementCreator: ElementCreator<*>) { with(elementCreator) { - val renderedInput = input(type = type) { inputElement -> + input(type = type) { inputElement -> var inputClassList: KVal> = kval(listOf("input")) with(inputElement) { @@ -79,8 +79,6 @@ class BulmaInput( } } - - return renderedInput } }