v0.13.1 is a fairly substantial release under the hood (~90 commits since v0.13.0!). Most of the effort was around two major areas:
- Better support related to creating full stack apps
- New features and tons of cleanup for the popup widget
but with a bunch of other miscellaneous changes as well. Let's break this down into more detail!
Backend
- Gradle exports now build a
server.jarand bundle it in.kobweb/server/server.jar, along withstart.shandstart.batscripts.- This makes it trivial to run Kobweb on a general web server hosting service.
- For example, in a Docker file, you can export your site and then use
.kobweb/server/start.shas theENTRYPOINTfor serving it. - A new blog post is in the pipeline for how to deploy a full stack Kobweb site on render.com. Brave users who understand docker and may want to try to figure things out for themselves can take a look at the Dockerfile for this project now!
- You can optionally define a
KOBWEB_JAVA_HOMEenvironment variable if you want to configure a particular JVM for the Kobweb
server to run on. - Changed all API methods (e.g.
window.api.post) from returning a nullable response result to a non-null result (but they can now throw exceptions). Newtryversions are provided which mimic the previous case.- For example:
window.api.get("id")!!.let { bodyBytes -> ... }should change to eitherwindow.api.get("id").let { bodyBytes -> ... }ORwindow.api.tryGet("id")?.let { bodyBytes -> ... } ?: run { ... handle error case here } - The
tryversions of the HTTP methods will log more information to the console in the case of failure, unlesswindow.api.logOnErroris set tofalse(debug runs default to true, release runs set to false) - If a kobweb server is running in dev mode and one of the endpoints throws an exception, logging now reports it in the console, which can be very convenient.
- For example:
- All API methods now take an optional
AbortControllerinstance which, if passed in, can be used to abort a fetch in progress. You can find updated docs in the ApiFetcher class, and you may wish to confirm with the official docs about AbortController.
Frontend
-
Made some under-the-hood fixes to
rememberPageContext, in order to...- stop causing unnecessary recompositions.
- work correctly in cases where it was failing to generate recompositions, for example when navigating between different URLs that mapped to the same underlying dynamic route.
-
Introduced a new
pageContext.routeproperty, whichparamsandfragmenthave moved under. Users may get deprecation warning about this. -
A handful of new CSS
Modifiers:- aspect-ratio
- line-height
- text-overflow
- touch-action
-
Fixed an issue with the
toStringmethod for HSA colors (the output was human readable but not parsed by CSS) -
Added missing APIs so users can fetch the raw element ref for
SpanTextandDivTextelements.
Silk
-
Slew of Popup changes
- Popups now fade out before closing, instead of popping out of existence.
- Popups now show up on focus gained / lost, not just on mouse over.
- This is useful for people navigating with the keyboard.
- Popups now take optional
showDelayMsandhideDelayMsparameters, which control timing around how long it takes for the any popup to show and hide itself, respectfully. - Popups now take an optional
stayOpenStrategyparameter, which can be used as a way to control when a popup, once opened, should stay open.- By default, tooltips will close whenever the mouse is moved away from the target element, while popups will close if the mouse is moved away from the target element unless the mouse has moved over the popup itself or some child element inside the popup has gained focus.
- A
ManualStayOpenStrategyis provided to make it easy for the caller to control this behavior. For example, you can put a complex form inside the popup with a "close" button, and have the popup get dismissed whenever the user presses that "close" button.val manualStrategy = remember { ManualStayOpenStrategy() } Popup(..., stayOpenStrategy = manualStrategy) { ... Button(onClick = { manualStrategy.shouldStayOpen = false }) { Text("Close") } }
- Fixed an issue where popups could get into a state where they would stop showing up for some targets.
- Fixed popup behavior on mobile, where sometimes a popup would show up and stay stuck open.
- HUGE thanks to one of the members in my community (who wishes to stay anonymous) for their immense amount of help testing and pushing this feature. I couldn't have done it without them. If they're reading this, they know who they are, and that I am immeasurably grateful.
-
Added new
modifyComponentStyleandmodifyComponentVariantAPIS- This is in addition to the existing
replaceAPIs. This version instead adds changes in addition to base styles, instead of replacing them outright, which can be useful if Silk ever tweaks its styles in the future.
- This is in addition to the existing
-
(Potentially backwards incompatible)
rememberBreakpointnow returns aBreakpointvalue directly, instead of aState<Breakpoint>- In other words, change this code
val bp by rememberBreakpoint()intoval bp = rememberBreakpoint() - Most cases of the previous version of the code will turn into a deprecation, but this may cause a compile error depending on what some users did with the returned state value.
- In other words, change this code
Gradle
- You can now configure exports to not include a source map
- In your build script:
kobweb { export { includeSourceMap.set(false) } } - Useful if you intentionally want your site to remain obscure and minimized to users
- In your build script:
- Fixed an exception that would happen when calling
npmdependencies that started occuring around Gradle 8.0 or 8.1. - Playwright has been updated to a newer version, which should hopefully address export slowdown that some users have been reporting on Mac M machines.
