Warning This library has been archived and no future work is planned. kotlin-wrappers has made it significantly easier to define functional components since this compiler plugin was created. Also, Compose for Web exists and provides a similar code style this compiler plugin was attempting to achieve.
Writing functional components with Kotlin/JS for React is great but requires a bit of boilerplate which makes each new component require some setup. Most of this boilerplate is extremely simple, perfect for automation.
Consider the following Kotlin/JS DOM builder function:
fun RBuilder.Hello(name: String) {
+"Hello, $name"
}
This function adds text to the DOM but does not support any React hooks because it is not currently a React functional component. To do so requires a fair amount of boilerplate:
private external interface HelloProps : Props {
var name: String
}
private val HELLO_COMPONENT = fc<HelloProps>("Hello") { props ->
+"Hello, ${props.name}"
}
fun RBuilder.Hello(name: String) {
child(HELLO_COMPONENT) {
attrs.name = name
}
}
With the Kotlin compiler plugin provided by this library, making the original function a React component is as simple as adding an annotation! (and Gradle dependency stuff)
@RFunction
fun RBuilder.Hello(name: String) {
+"Hello, $name"
}
The compiler plugin automatically generates the Props
interface and the functional component property. It then
rewrites the original function to add the component as a child and automatically assigns all the component property
attributes. Basically doing all the boilerplate for you automatically! Magic!
This library is a work in progress and requires using Kotlin/JS IR backend for compilation and often requires a specific version of Kotlin as well. The Kotlin/JS IR backend is currently in preview and is not recommended for production. Use at your own risk!
Kotlin Version | Plugin Version |
---|---|
1.4.10 | 0.2.1 |
1.4.20 | 0.3.0 |
1.4.30 | 0.4.0 |
1.5.0 | 0.5.0 |
1.5.10 | 0.5.1 |
1.5.30 | 0.6.0 |
1.6.10 | 0.7.0 |
See the sample directory for a working project using this compiler plugin which is also available live.
Builds of the Gradle plugin are available through the Gradle Plugin Portal.
plugins {
kotlin("jvm") version "1.6.10"
id("com.bnorm.react.kotlin-react-function") version "0.7.0"
}
Annotations are automatically included, but if they are needed separately, the dependency is available via Maven Central:
implementation("com.bnorm.react:kotlin-react-function:0.7.0")
Make sure Kotlin/JS is configured to compile using IR!
kotlin {
js(IR) {
// ...
}
}
To set the key of a React functional component, use the @RKey
annotation on a single parameter to a @RFunction
annotated function.
@RFunction
fun RBuilder.ListItem(@RKey item: Item) {
...
}
This uses the toString()
value of the annotated parameter as the key for the component. If the value of the key needs
to be controlled more explicitly, mark an unused parameter as the key.
@RFunction
fun RBuilder.Component(... other parameters ..., @RKey key: String) {
// `key` doesn't need to be used to be set as the key of the component
}
If the @RKey
annotated parameter is null
, then the string "null"
will be set as the component key. It is also
possible to use default parameters to derive the key from another parameter.
The @RFunction
annotation supports functions with generics.
@RFunction
fun <T> RBuilder.GenericList(items: List<T>, onItem: RBuilder.(T) -> Unit) {
div {
for (item in items) {
onItem(item)
}
}
}