DataGrid
Virtual cards with stable SSR and hydration windows.
Grid virtualization
Card collections should stay light even when they grow.
A remote in-memory source exposes 180 cards. DataGrid renders the visible rows, prefetches nearby ranges, and keeps crawlable HTML pagination.
Remote card grid
The scrolling header and every card are composed through contextual Scala JS UI 1.0 DSL renderers.
180 remote cards · the header scrolls with the virtual surface
Research
Atlas Memo 31
Dense notes, references, and open questions in one card.
Commerce
Northwind 32
A product teaser with enough structure for catalog browsing.
Operations
Signal Room 33
Metrics and ownership should still feel quiet at scale.
Editorial
Amber Draft 34
A story card with room for title, deck, and routing metadata.
Finance
Mint Ledger 35
Stable dimensions make grids predictable for dashboards too.
Archive
Violet Tape 36
Long collections stay light when only the viewport is rendered.
Research
Atlas Memo 37
Dense notes, references, and open questions in one card.
Commerce
Northwind 38
A product teaser with enough structure for catalog browsing.
Operations
Signal Room 39
Metrics and ownership should still feel quiet at scale.
Editorial
Amber Draft 40
A story card with room for title, deck, and routing metadata.
Select a card to inspect the reactive cell state.
Sizing
Preferred width, flexible columns
The preferred card width chooses a column count; actual widths fill the viewport.
Remote
Range loading follows the viewport
Unloaded positions remain stable placeholder cells while nearby data is requested.
SSR hosting
Query-aware servers render real windows
offset and limit select deterministic HTML on a request-aware server. The GitHub Pages snapshot applies query changes after hydration.
DataGrid DSL
The renderer describes one card while the control owns layout and loading.
scala
dataGrid[Tile](tiles) {
itemWidthPx = 240
itemHeightPx = 196
gapPx = 16
overscanRows = 1
prefetchItems = 24
crawlable = true
crawlId = "showcase-tiles"
cellRenderer = { (tile, index) =>
div { text(tile.title) {} }
}
header {
div { text("Scrolling grid header") {} }
}
}