Example of usage (reactFunction is my sugar):
data class PinSectionProps(
val pinList: List<Pin>,
val scale: PinButtonScale = PinButtonScale.Small,
val canDrag: Boolean,
val className: String
) : RProps
val PinSection = reactFunction<PinSectionProps> { (pinList, scale, canDrag, className) ->
styledDiv {
etc etc
Code that does it (using the RClass<P> type for various reasons I can’t remember at the moment):
inline fun <reified P : RProps> reactFunction(crossinline function: RBuilder.(P) -> Unit): RClass<P> =
buildReactFunction(P::class) { props ->
buildElement { function(props) }
}
fun <P : RProps> buildReactFunction(kClass: KClass<P>, builder: (props: P) -> ReactElement) = { props: P ->
ensureKotlinClassProps(props, kClass.js)
.let(builder)
}.unsafeCast<RClass<P>>()
private fun <P : RProps> ensureKotlinClassProps(props: P, jsClass: JsClass<P>): P = if (props::class.js == jsClass) {
props
} else {
val newProps = js("new jsClass()")
objectAssign(newProps, props)
newProps.unsafeCast<P>()
}