Dashboard Layouts
Build responsive dashboards where widgets depend on each other's dimensions.
Overview
Dashboards have complex layout dependencies. A sidebar resize affects content width, which affects chart dimensions, which affects table column widths. Inval tracks all of this automatically.
Example: Multi-Widget Dashboard
dashboard.ts TYPESCRIPT
import { input, node, batch } from '@blu3ph4ntom/inval'
// External inputs
const dashboardWidth = input(1200)
const sidebarWidth = input(300)
const zoomLevel = input(1)
// Content area
const contentWidth = node({
dependsOn: { dash: dashboardWidth, sidebar: sidebarWidth },
compute: ({ dash, sidebar }) => dash - sidebar
})
// Chart: 60% of content
const chartWidth = node({
dependsOn: { content: contentWidth },
compute: ({ content }) => content * 0.6
})
// Chart height scales with zoom
const chartHeight = node({
dependsOn: { zoom: zoomLevel },
compute: ({ zoom }) => 400 * zoom
})
// Table: 40% of content
const tableWidth = node({
dependsOn: { content: contentWidth },
compute: ({ content }) => content * 0.4
})
// Table row height scales with zoom
const tableRowHeight = node({
dependsOn: { zoom: zoomLevel },
compute: ({ zoom }) => 40 * zoom
})
// --- Usage ---
// Initial layout
chartWidth.get() // 540
tableWidth.get() // 360
chartHeight.get() // 400
tableRowHeight.get() // 40
// Resize sidebar: content changes, chart and table both update
sidebarWidth.set(400)
chartWidth.get() // 480
tableWidth.get() // 320
// chartHeight and tableRowHeight NOT dirty
// Change zoom: only zoom-dependent nodes dirty
zoomLevel.set(1.5)
chartHeight.get() // 600
tableRowHeight.get() // 60
// chartWidth and tableWidth NOT dirty
// Atomic resize
batch(() => {
dashboardWidth.set(1400)
sidebarWidth.set(350)
}) Tip
Notice how changing zoom doesn't invalidate chart width or table width. The dependency graph ensures only affected nodes recompute.