-
-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
118 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
--- | ||
title: Laminar v17.1.0 & stickers | ||
author: Nikita | ||
authorURL: https://twitter.com/raquo | ||
--- | ||
|
||
New Airstream features: splitting Vars, and zooming into Vars without an owner. | ||
|
||
<!--truncate--> | ||
|
||
> Laminar is a Scala.js library for building web application interfaces and managing UI state. Learn more in [a few short examples](https://demo.laminar.dev) or [one long video](https://www.youtube.com/watch?v=L_AHCkl6L-Q). | ||
|
||
## Releases | ||
|
||
* [Laminar](https://github.com/raquo/laminar) 17.1.0 | ||
* [Airstream](https://github.com/raquo/airstream) 17.1.0 | ||
|
||
|
||
## New Airstream Features | ||
|
||
|
||
### Splitting Var-s | ||
|
||
You could always `split` a `Signal[Collection[A]]` into N individual `Signal[A]`, but now you can also directly split a `Var[Collection[A]]` into N individual `Var[A]` that are linked to the original `Var[Collection[A]]`. | ||
|
||
For example, in the example below, the user's name in both `userVar` and `usersVar` is updated when you type the new name into the input text box. | ||
|
||
```scala | ||
case class User(id: String, name: String) | ||
val usersVar = Var[List[User]](???) | ||
|
||
div( | ||
usersVar.split(_.id)((userId, initial, userVar) => { | ||
div( | ||
s"User ${userId}: ", | ||
input( | ||
value <-- userVar.signal.map(_.name), | ||
onInput.mapToValue --> { newName => | ||
userVar.update(_.copy(name = newName)) | ||
} | ||
) | ||
) | ||
}) | ||
) | ||
``` | ||
|
||
Previously in this situation, you would have needed to update `usersVar` manually by finding the user with `id == userId` and updating the list with the new user at that index. Now this is done behind the scenes just by updating `userVar`. | ||
|
||
Also, in addition to `split`, you can also use `splitMutate` on Vars that contain **mutable** collections. As the name implies, it works the same as regular `Var.split`, except that when you update `userVar`, it would **mutate** the collection in `usersVar` instead of creating a copy of it as is usually done with immutable collections. This may be more efficient when working with very large mutable collections. | ||
|
||
|
||
### Zoom into a Var without needing an Owner | ||
|
||
Airstream has had the `zoom` method to create derived vars for a while now: `Var.zoom(a => b)((a, b) => a)(implicit owner)`. Unfortunately, that method required an `Owner`, which made using it rather annoying. | ||
|
||
Recently, [@KitLangton](https://github.com/kitlangton) has [figured out](https://github.com/raquo/Airstream/issues/119) that this Owner isn't really needed, and so we now have a new `zoomLazy(a => b)((a, b) => a)` method that does not require an `Owner`, and otherwise works pretty much the same. One catch is that your `zoomIn` (`a => b`) function is now called lazily, so it shouldn't have side effects. In practice that shouldn't be a problem because this function typically just selects some field from an object. | ||
|
||
This small change should help a lot with ergonomics of local state management. | ||
|
||
We use the `zoomLazy` name to stay binary-compatible with 17.0.0 in this release, but in the next major release, `zoomLazy` will be renamed to `zoom`, and the old `zoom` will be renamed to `zoomStrict` and deprecated. | ||
|
||
|
||
### Small stuff | ||
|
||
* New: `.not` alias to the `.invert` operator on observables of booleans | ||
* The `Splittable` trait has two new methods: `foreach` and `findUpdate`. **Migration:** if you have custom instances of `Splittable` for non-standard collection types, make sure to review the default implementations of those methods for efficiency. | ||
|
||
|
||
## Laminar Stickers | ||
|
||
In case you missed it, I'm mailing out free Laminar stickers as a thank you to people who have, in one way or another, contributed to Laminar or the ecosystem. [Sign up here](https://docs.google.com/forms/d/e/1FAIpQLSdxwtT0-Yy9mxcyYoNPUwinAMzAojGviAY-pp8KARnf_NLxKA/viewform). | ||
|
||
<img src="/img/blog/laminar_stickers_1000.jpg" /> | ||
|
||
|
||
## Thank you | ||
|
||
Laminar development is kindly supported by [my sponsors](https://github.com/sponsors/raquo), and I am very grateful to be able to work on all this. | ||
|
||
|
||
<h4 class="x-like-h3">DIAMOND sponsor:</h4> | ||
|
||
<div class="-sponsorsList x-alignItemsStart x-justifyContentCenter"> | ||
<div class="-sponsor x-diamond x-company x-heartai"> | ||
<a class="x-noHover" href="https://www.heartai.net/"> | ||
<img class="-logo" src="/img/sponsors/heartai.svg" alt="" /> | ||
<div class="-tagline"><u>HeartAI</u> is a data and analytics platform for digital health and clinical care.</div> | ||
</a> | ||
</div> | ||
</div> | ||
|
||
**GOLD sponsors**: | ||
|
||
<div class="-sponsorsList x-alignItemsEnd"> | ||
<div class="-sponsor x-person x-yurique"> | ||
<img class="-avatar x-rounded" src="/img/sponsors/yurique.jpg" alt="" /> | ||
<div class="-text"> | ||
<div class="-name"><a href="https://github.com/yurique">Iurii Malchenko</a></div> | ||
</div> | ||
</div> | ||
<div class="-sponsor x-company x-aurinko"> | ||
<a class="x-noHover" href="https://www.aurinko.io/"> | ||
<img class="-logo" src="/img/sponsors/aurinko-light-250px.png" alt="" /> | ||
<div class="-tagline"><u>Aurinko</u> is an API platform for workplace addons and integrations.</div> | ||
</a> | ||
</div> | ||
<a class="-sponsor x-person x-tawasal" href="https://tawasal.ae"> | ||
<img class="-avatar" src="/img/sponsors/tawasal.svg" alt="" /> | ||
<div class="-text"> | ||
<div class="-name">Tawasal</div> | ||
<div class="-description">Secure multi-purpose messenger and superapp, offering free voice, text, video conferencing and lifestyle services.</div> | ||
</div> | ||
</a> | ||
<div class="-sponsor x-empty"> | ||
<!-- filler for layout purposes --> | ||
</div> | ||
</div> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.