The big feature with this release is the new Checkbox Silk widget:
silk-checkboxes.mp4
As you can see, checkboxes are fairly configurable -- you can tweak their size, their colors, and even their icons.
Checkboxes use an API inspired by Android Jetpack Compose. At their simplest, the code looks like:
var checked by remember { mutableStateOf(true) }
Checkbox(checked, onCheckedChange = { checked = it })While Checkbox works with a simple "on / off" concept, TriCheckbox is used for checkboxes that can be on, off, or indeterminate. The "Parent" checkbox in the video above is a TriCheckbox. They work very similar to a normal Checkbox:
var checked by remember { mutableStateOf(CheckedState.Indeterminate) }
TriCheckbox(checked, onCheckedChange = { checked = it })Silk
- New
Checkboxwidget - New
Labelwidget- Labels are a way you can associate text with HTML form controls (currently Switches, Checkboxes, and Inputs).
- Once bound, screen readers can tie label text with the control; also, clicking on a label will affect the target element it is tied to.
- Note that labels only work with special form elements. Tying a label to some random element, say a div, will have no effect.
- Began adding some initial SVG icons that projects can use, especially useful if you don't want to pull in large dependencies like Font Awesome or Material Design Icons.
Frontend
setTimeoutandsetIntervalmethods have been migrated to use the idiomatic KotlinDurationclass instead of raw millisecond values- Added
Modifier.textTransform - Made improvements to
SVGelement APIs- All
SVGchildren types (e.g. rectangles, circles, paths, polygons, etc.) are now supported (although the Compose HTML SVG bindings are still fairly barren; we added #307 for now to make sure we address improving this situation via extension methods before 1.0)
- All
- Added some file util methods around reading file bytes
- Added some element util methods have been added to Kobweb
descendantsBfs,descedantsDfs, andancestorssequences are provided to make it trivial to walk a DOM tree in either direction from some element.generateUniqueIdallows you to generate a random ID that you can safely set on any element without worrying about an ID conflict.
Backend
- The ApiStream factory method that accepts a route override is deprecated. Instead, tag your object with an
@Apiannotation.- It's unlikely any users are even using this, but if you were, sorry! This change is necessary as we prepare to migrate some of our Gradle logic over to KSP.
// Before val echo = ApiStream("echo") { ... } // After @Api("echo") val echo = ApiStream { ... }
- It's unlikely any users are even using this, but if you were, sorry! This change is necessary as we prepare to migrate some of our Gradle logic over to KSP.
Notes
CheckedState
With TriCheckbox and CheckedState, you are often trying to determine if some parent checkbox should be checked, unchecked, or indeterminate based on children boolean values. CheckedState makes this easy by providing from and toBoolean conversions for you:
var child1Checked by remember { mutableStateOf(false) }
var child2Checked by remember { mutableStateOf(false) }
TriCheckbox(
CheckedState.from(child1Checked, child2Checked), // <<< From booleans
onCheckedChange = {
val checked = it.toBoolean() // <<< To boolean
child1Checked = checked
child2Checked = checked
},
) { Text("Parent") }
Column(Modifier.margin(left = 1.cssRem)) {
Checkbox(child1Checked, onCheckedChange = { child1Checked = it }) { Text("Child 1") }
Checkbox(child2Checked, onCheckedChange = { child2Checked = it }) { Text("Child 2") }
}Label
Setting up HTML labels by hand can be pretty tedious -- you have to make sure the element you are targeting has a unique ID which you then specify on the label. The Label composable provided by Compose HTML works this way.
With Silk, we now provide our own convenience Label composable. We use Silk's ElementTarget class to make it a lot easier and more intuitive to use:
Row {
Switch(...)
Label(ElementTarget.PreviousSibling, "Dark Mode")
}
Row {
Switch(...)
Label(ElementTarget.PreviousSibling, "High Contrast")
}The code above will automatically create temporary IDs behind the scenes to ensure the labels and the switches are correctly connected.
Thanks!
Finally, thanks to first-time contributor @tungbq who helped us clean up a bunch of comments, migrating them to use the more appropriate @see documentation attribute.
There are all manner of issues left before we hit 1.0, and we appreciate anyone who offers help no matter how big or small -- it all moves the needle forward!
Full Changelog: v0.13.11...v0.13.12