fritz2 v0.8 Release Notes

Release Date: 2020-12-03 // 11 months ago
  • ๐Ÿ’ฅ breaking changes

    ๐Ÿš€ This release contains changes that break code written with earlier versions. Hopefully these are the last major api-changes prior to fritz2 1.0:

    Setting attributes per function

    In fritz2 0.8 we decided to use functions to set attribute values instead of vars with delegation.
    ๐ŸŽ That way you do not have to wrap constant values in a Flow anymore. This yields better performance and the const()-function could be removed. For convenience reasons we also added a new function asString for Flows to
    convert a Flow to a Flow<String> by calling the toString() method internally.

    input { type("text") // native value(myStore.data) // flow name(otherStore.data.asString()) // otherStore.data is not a Flow of String}
    

    RenderContext replaces HtmlElements

    ๐Ÿ‘ We renamed the HtmlElements interface to RenderContext, because we think this name better fits the Kotlin DSL approach.
    The idea behind it is that every render function creates a new RenderContext in which
    ๐Ÿ†• new Tags can be created. This also means that you must replace the receiver type in your custom component-functions accordingly:

    val errorStore = storeOf("some text")// own componentfun RenderContext.errorText(text: String): P { return p("error") { +text } } errorStore.data.render { //this: RenderContext errorText(it) }
    

    โž• Adding Text and Comments

    We clarified the creation of TextNodes in Tags. Now you use unary +-operator for constant Strings
    to append text at this position to your Tag. If you have a Flow, call asText() instead.
    To create a CommentNode, you can use the !-operator and asComment() analogous. This intentionally follows a different approach in contrast to the attribute functions so it can be distinguished more easily.

    p { +"Hello " myStore.data.asText() !"this is a comment" myStore.data.asComment() }
    

    Evolution of render() and renderEach()

    ๐Ÿšš Using former fritz2-versions you mapped a Flow of data to a Flow of Tags and created a MountPoint explicitly by calling bind() at some place in your rendering. This was error prone. Since nobody would do anything with a Flow<Tag> other than binding it, all render functions now implicitly create the mount point and therefore no bind() is necessary anymore. It has been removed completely.

    val myStore = storeOf(listOf("a","b","c")) render { ul { myStore.data.renderEach { li { +it } } // no .bind() here anymore } }
    

    ๐ŸŽ For performance reasons the render-functions prior to version 0.8 did not allow more than one root-element. In version 0.8 the standard render allows you to add as many root elements to your context as you want or even none:

    val myStore = storeOf(42)// renders multiple root-elementsmyStore.data.render { repeat(it) { div { +"one more" } } }// does only render something if value is large enoughmyStore.data.render { if (it \> 100) { div { +"number" } } }
    

    ๐ŸŽ If you you do not need this feature (because you know you will always have exactly one root-element) use renderElement() instead to get (slightly) improved performance.

    ๐ŸŽ render() and renderElement() now reserve their place in the DOM until the content is rendered by using a temporary placeholder. Since this costs some performance you can disable it when you are sure that there are no sibling-elements on the same level in your DOM-tree by setting renderElement(preserveOrder = false). Use this when you have to render lots of elements (in huge lists, tables, etc.).

    Instead of someListFlow.each().render {...}.bind() you now simply write someListFlow.renderEach {...}. This is analog for all flavors of renderEach on Stores and Flows with and without an idProvider.
    Please note that renderEach() still allows only one root-element (like renderElement)!

    Tracker offers Flow<Boolean>

    ๐Ÿ“„ Tracker now implements Flow<Boolean> instead of Flow<String?>so it adopts better to most use-cases. Find an example here.

    ๐Ÿ†• new features

    • ๐Ÿ‘ Websocket support PR#175
    • Styling and Components PR#176

    ๐Ÿ‘Œ improvements

    • โšก๏ธ update all dependencies to latest version PR#166
    • extend Router functionality PR#197
    • โฌ†๏ธ upgraded Dokka-version and moved to html for api-docs PR#194
    • annotation processor visibility option PR#178
    • โœ… use local test server PR#165

    ๐Ÿ›  fixed bugs

    • ๐Ÿ›  fix memory leaks and performance issues PR#180 PR#185
    • no trailing slash in remote PR#167
    • ๐Ÿ›  fix boolean attribute delegates PR#172

Previous changes from v0.7.2

  • Small patch resolving a memory issue related to coroutine scopes.