Sketch the board
Fable.Lit / browser-native animation
Switch the theme for a page-wide crossfade. Remove a basket item to see rows glide into place, then reset to replay. Try the counter, palette, panel and shelf too, and drag cards across the board at the bottom.
Animations follow your reduced-motion preference. Browsers without View Transitions still update normally.
The page is light, and was already when it arrived.
The six cards below arrived as HTML from .NET. Each is an independent Elmish program that adopts its own markup when the script loads: the nodes stay, and the loops never touch each other. The third arrived inside a shadow root of its own, styles included, which is why the page's card styling stops at its edge. The fourth is the other way round: its shadow root is only a frame with slots, and the card it frames is ordinary light DOM, styled by this page like the two at the top. The last two share one piece of state that only the server knows in time to matter — whether you asked for dark — so it is written into the page below them, and into the html element before any of this was sent. Both islands start from the value their markup was rendered from, neither knows about the other, and the page is never briefly the wrong colour. A seventh card is not an island at all: it is a custom element, which the browser builds and which reads that same state from the store. It arrived drawn like the others, inside its own shadow root, and took that over. The eighth is an island with a component in it. The island adopts its markup and hands the component its level, and only then does the component take over the shadow root that arrived inside its tag. The ninth is a board, an island like the first two that the server draws standing still, and each card on it is a component that drags itself. The dragging, and the gliding from lane to lane, belong to the browser alone.
Value: 0
Remove a row and watch the others move into place.
| Crate | 40 | |
| Pallet | 2 | |
| Drum | 7 |
Total: 49 in 3 lines.
Picked: sabi
Step 1 of 3: measure
This card was not told about the switch. It reads the same store, so it says light too.
The server drew this too, inside the shadow root of
<bfb-theme-badge>, and the component took it over. It
says light because the server and the store
agree.
It can write to the store as well as read it, and the two islands above follow — the same way this one follows them.
Remove it and put it back — document.querySelector("bfb-theme-badge").remove()
— and it unsubscribes and resubscribes on its own. That is what a
component gets for free and an island needs
Lit.trackConnection for.
Level 3 of 5. The island keeps the number and hands it to the meter, which is a component.
Drag a card to another lane, or use its arrows. The cards glide, arrive and leave on the same View Transitions as the basket rows.
Sketch the board
Wire the reducer
Render on the server
Measure the bundle