Layout and surfaces
Compose windows, grids, stacks, scroll regions, and reusable application-owned UI modules.
Updated for Zui 0.0.5·1 minute read
Surfaces frame the application
Desktop applications start with app. Omarchy adapters can host the same application UI in panels and bar widgets.
require "zui"
destinations = [
{ label: "Overview", icon: :house },
{ label: "Activity", icon: :clock },
{ label: "Settings", icon: :gear }
]
Zui.app do
state :section, 0
app :main, title: "Operations", width: 1100, height: 760 do
row_layout spacing: 20 do
rail = navigation_rail destinations,
current_index: state.section,
extended: true,
width: 220
on rail, :change do |payload|
state.section = payload.fetch("current_index", payload["index"])
end
scroll fill_width: true, fill_height: true do
column spacing: 16 do
label "Operations", size: 32, bold: true
grid_layout columns: 2, spacing: 12 do
card(padding: 18) { label "Requests: 14.2k" }
card(padding: 18) { label "Latency: 42 ms" }
end
end
end
end
end
end
Prefer layout constraints
Use fill_width, preferred_width, and the layout containers when content should adapt. Explicit dimensions remain useful for media, canvases, and deliberate fixed surfaces.
Keep reusable UI scoped
require "zui"
module OperationsUI
def metric_card(label, value)
card padding: 18, spacing: 8 do
text label, color: "#8b8b92"
label value, size: 28, bold: true
end
end
end
application = Zui::Application.new(ui: OperationsUI) do
app :main, title: "Operations", width: 760, height: 520 do
grid_layout columns: 2, spacing: 12 do
metric_card "Requests", "14.2k"
metric_card "Latency", "42 ms"
end
end
end
application.run