aboutsummaryrefslogtreecommitdiff

KVision Logo

KVision

Object oriented web framework for Kotlin/JS.

Travis CI Download License: MIT

KVision allows you to build modern web applications with the Kotlin language, without any use of HTML, CSS or JavaScript.

KVision prefers the imperative style of programming. It's object oriented and supports many well known OOP design patterns. It gives you a hierarchy of many different components, which are used as a builder blocks for the application GUI.

KVision's design is quite similar to many non-web UI programming libraries including Swing, JavaFX, QT, WinForms and Flutter.

KVision contains innovative connectivity interface for Ktor, Jooby and Spring Boot frameworks on the server side, which allows to build full-stack, multiplatform applications with shared common code.

KVision is being actively developed. Please create an issue for any bugs or feature requests.

Features

Documentation

The comprehensive KVision guide is published on GitBook.

Full API documentation (KDoc) is available at https://rjaros.github.io/kvision/api/.

Quickstart

Development

  1. Download KVision examples from GitHub:

    git clone https://github.com/rjaros/kvision-examples.git
    
  2. Enter one of the examples directory:

    cd kvision-examples/showcase                        (on Linux)
    cd kvision-examples\showcase                        (on Windows)
    
  3. Run Gradle incremental build with:

    ./gradlew -t run                                    (on Linux)
    gradlew.bat -t run                                  (on Windows)
    
  4. Open http://localhost:8088/ in your browser.

  5. Play with the code and see your changes immediately in the browser.

Production

To build complete application optimized for production run:

    ./gradlew -Pprod=true distZip                       (on Linux)
    gradlew.bat -Pprod=true distZip                     (on Windows)

Application package will be saved as build/distributions/showcase.zip.

Code samples

Hello world

    val root = Root("root")
    val label = Label("Hello world!")
    root.add(label)

Basic components interactions using type safe DSL builders

    Root("root") {
        hPanel(spacing = 20, alignItems = FlexAlignItems.CENTER) {
            val label = label("Not yet clicked.")
            var count = 0
            button("Click me") {
                onClick {
                    label.content = "You clicked the button ${++count} times."
                }
            }
        }
    }

Tab panel with JavaScript routing

    val firstPanel = Tag(TAG.DIV, "First")
    val secondPanel = Tag(TAG.DIV, "Second")
    val thirdPanel = Tag(TAG.DIV, "Third")

    Root("root").add(TabPanel().apply {
        addTab("First", firstPanel, route = "/first")
        addTab("Second", secondPanel, route = "/second")
        addTab("Third", thirdPanel, route = "/third")
    })

Type safe forms

    @Serializable
    data class Model(val username: String? = null, val password: String? = null)

    Root("root").add(FormPanel {
        add(Model::username, Text(label = "Username"), required = true)
        add(Model::password, Password(label = "Password"), required = true)
        add(Button("OK").onClick {
            val data: Model = this@FormPanel.getData()
            println("Username: ${data.username}")
            println("Password: ${data.password}")
        })
    })

Data binding with observable data model

    data class Data(val text: String)

    val model = observableListOf(
        Data("One"),
        Data("Two"),
        Data("Three")
    )
    Root("root").add(DataContainer(model, { data, _, _ ->
        Label(data.text)
    }, HPanel(spacing = 10)))

    GlobalScope.launch { // Kotlin coroutines
        while (true) {
            delay(1000)
            model.reverse()
        }
    }