9

I'm trying to use this lib in my create-react-kotlin-app:

https://material-ui-next.com/

I want to generate bunch of type safe wrappers. I started like this:

@file:JsModule("material-ui")

package material

import react.RState
import react.React
import react.ReactElement

external class Typography : React.Component<dynamic, RState> {
    override fun render(): ReactElement
}

...

fun RBuilder.typography(
    classes: String = "",
    variant: Variant = Variant.body1,
    align: Align = Align.inherit,
    color: Color = Color.default,
    gutterBottom: Boolean = false,
    noWrap: Boolean = false,
    paragraph: Boolean = false,
    handler: RHandler<dynamic>
) = child(Typography::class) {
    attrs {
        this.className = classes
        this.align = align.name
        this.color = color.name
        this.variant = variant.name
        this.gutterBottom = gutterBottom
        this.noWrap = noWrap
        this.paragraph = paragraph
    }
    handler()
}

And use it like:

typography(variant = Variant.title, color = Color.inherit) {
    +"Hello World"
}

Is it correct approach?

deviant
  • 3,539
  • 4
  • 32
  • 47

2 Answers2

1

Indeed that is the correct way but can make it to be the best as follows

MaterialUi.kt

@file:JsModule("material-ui")

package material

import react.RState
import react.RProps
import react.React
import react.ReactElement

external interface TypographyProps : RProps {
    var className: String
    var align : String
    var color : String
    var variant : String
    var gutterBottom : String
    var noWrap : String
    var paragraph : String
}

@JsName("Typography")
external class Typography : RComponent<TypographyProps, RState> {
    override fun render(): ReactElement
}

And then create another file, say

MaterialUiDsl.kt

fun RBuilder.typography(
    classes: String = "",
    variant: Variant = Variant.body1,
    align: Align = Align.inherit,
    color: Color = Color.default,
    gutterBottom: Boolean = false,
    noWrap: Boolean = false,
    paragraph: Boolean = false,
    handler: RHandler<TypographyProps> // notice the change here
) = child(Typography::class) {
    attrs {
        this.className = classes
        this.align = align.name
        this.color = color.name
        this.variant = variant.name
        this.gutterBottom = gutterBottom
        this.noWrap = noWrap
        this.paragraph = paragraph
    }
    handler()
}

If the above file already seems verbose to you (Like how I often feel), you can change it to just

MaterialUiDsl.kt

fun RBuilder.typography(handler: RHandler<dynamic>) = child(Typography::class,handler)

The you can use it whenever like this

typography {
    attr {
        className = "my-typo"
        color = "#ff00ff"
        //. . .
    }
}

Easy peasy

andylamax
  • 1,858
  • 1
  • 14
  • 31
0

I'm also interested in adding a ReactJS 3rd party component to Kotlin code. Please take a look at the following post, I'd appreciate any feedback regarding the solutions proposed there:

How to import node module in React-Kotlin?

Big Rich
  • 5,864
  • 1
  • 40
  • 64