Layout
Plushie's layout model mirrors iced's. Understanding it is essential for building UIs that size and position correctly.
Length
Length controls how a widget claims space along an axis.
| Plushie value | Iced equivalent | Meaning |
|---|---|---|
:fill |
Length::Fill |
Take all remaining space |
[:fill_portion, n] |
Length::FillPortion(n) |
Proportional share of remaining space |
:shrink |
Length::Shrink |
Use minimum/intrinsic size |
200 or 200.0 |
Length::Fixed(200.0) |
Exact pixel size |
# Fill available width
column(width: :fill) do ... end
# Fixed width
container("sidebar", width: 250) do ... end
# Proportional: left takes 2/3, right takes 1/3
row do
container("left", width: [:fill_portion, 2]) do ... end
container("right", width: [:fill_portion, 1]) do ... end
end
# Shrink to content
("save", "Save", width: :shrink)
Default lengths
Most widgets default to :shrink for both width and height. Layout
containers (column, row) typically default to :shrink but grow to
accommodate their children.
Padding
Padding is the space between a widget's boundary and its content.
| Plushie value | Meaning |
|---|---|
10 |
Uniform: 10px on all sides |
[10, 20] |
Axis: 10px vertical, 20px horizontal |
{top: 5, right: 10, bottom: 5, left: 10} |
Per-side |
0 |
No padding |
container("box", padding: 16) do ... end
container("box", padding: [8, 16]) do ... end
container("box", padding: {top: 0, right: 16, bottom: 8, left: 16}) do ... end
Padding is accepted by container, column, row, scrollable,
button, text_input, and text_editor.
Spacing
Spacing is the gap between children in a layout container.
column(spacing: 8) do
text("First")
text("Second") # 8px gap between First and Second
text("Third") # 8px gap between Second and Third
end
Spacing is accepted by column, row, and scrollable.
Alignment
Alignment controls how children are positioned within their parent along the cross axis.
align_x (horizontal alignment in a column)
| Value | Meaning |
|---|---|
:start or :left |
Left-aligned |
:center |
Centered |
:end or :right |
Right-aligned |
align_y (vertical alignment in a row)
| Value | Meaning |
|---|---|
:start or :top |
Top-aligned |
:center |
Centered |
:end or :bottom |
Bottom-aligned |
# Center children horizontally in a column
column(align_x: :center) do
text("Centered")
("ok", "OK")
end
# Center a single child in a container
container("page", width: :fill, height: :fill, center: true) do
text("Dead center")
end
The center: true shorthand on container sets both align_x: :center
and align_y: :center.
Layout containers
column
Arranges children vertically (top to bottom).
column(id: "main", spacing: 16, padding: 20, width: :fill, align_x: :center) do
text("title", "Title", size: 24)
text("subtitle", "Subtitle", size: 14)
end
Props: spacing, padding, width, height, align_x.
row
Arranges children horizontally (left to right).
row(spacing: 8, align_y: :center) do
("back", "<")
text("Page 1 of 5")
("next", ">")
end
Props: spacing, padding, width, height, align_y, wrap (new
in plushie-iced -- wraps children to next line when they overflow).
container
Wraps a single child with padding, alignment, and styling.
container("card", padding: 16, style: :rounded_box, width: :fill) do
column do
text("Card title")
text("Card content")
end
end
Props: padding, width, height, align_x, align_y, center,
style, clip.
scrollable
Wraps content in a scrollable region.
scrollable("list", height: 400, width: :fill) do
column(spacing: 4) do
items.each do |item|
text("item:#{item.id}", item.name)
end
end
end
Props: width, height, direction (:vertical, :horizontal,
:both), spacing.
stack
Overlays children on top of each other (z-stacking). Later children are on top.
stack do
image("bg", "background.png", width: :fill, height: :fill)
container("overlay", width: :fill, height: :fill, center: true) do
text("overlay_text", "Overlaid text", size: 48)
end
end
space
Empty spacer. Takes up space without rendering anything.
row do
text("Left")
space(width: :fill) # pushes Right to the far right
text("Right")
end
grid
Arranges children in a grid layout (new in plushie-iced).
grid(id: "gallery", columns: 3, spacing: 8) do
items.each do |item|
image("img:#{item.id}", item.url, width: :fill)
end
end
Common layout patterns
Centered page
container("page", width: :fill, height: :fill, center: true) do
column(spacing: 16, align_x: :center) do
text("welcome", "Welcome", size: 32)
("start", "Get Started")
end
end
Sidebar + content
row(width: :fill, height: :fill) do
container("sidebar", width: 250, height: :fill, padding: 16) do
nav_items(model)
end
container("content", width: :fill, height: :fill, padding: 16) do
main_content(model)
end
end
Header + body + footer
column(width: :fill, height: :fill) do
container("header", width: :fill, padding: [8, 16]) do
header(model)
end
scrollable("body", width: :fill, height: :fill) do
body_content(model)
end
container("footer", width: :fill, padding: [8, 16]) do
(model)
end
end