Skip to main content

Overview

The Size enum defines how elements calculate their width and height. It supports various sizing modes including pixels, percentages, fill, flex, and custom functions.

Size Variants

Pixels

Fixed size in pixels:
use freya::prelude::*;

Size::px(100.0)
Size::Pixels(Length::new(100.0))

Percentage

Size relative to parent (0-100):
Size::percentage(50.0)  // 50% of parent
Size::Percentage(Length::new(50.0))

Fill

Expands to fill available space:
Size::fill()
Size::Fill

Fill Minimum

Fills available space but respects content minimum:
Size::fill_minimum()
Size::FillMinimum

Inner (Auto)

Sizes based on content (default):
Size::inner()
Size::Inner  // Default

Root Percentage

Size relative to root element:
Size::root_percentage(50.0)  // 50% of root
Size::RootPercentage(Length::new(50.0))

Flex

Flexible size with grow factor:
Size::flex(1.0)  // Flex grow factor
Size::Flex(Length::new(1.0))

Custom Function

Dynamic size calculated at runtime:
use freya::prelude::*;

let size = Size::Fn(Box::new(SizeFn::new(|ctx| {
    Some(ctx.parent * 0.5 + 20.0)
})));

// With data for equality comparison
let data = "my-size";
let size = Size::Fn(Box::new(SizeFn::new_data(
    |ctx| Some(ctx.parent * 0.5),
    &data
)));

Size Function Context

When using Size::Fn, the context provides:
pub struct SizeFnContext {
    pub parent: f32,           // Parent size
    pub available_parent: f32, // Available space in parent
    pub parent_margin: f32,    // Parent margin
    pub root: f32,            // Root element size
    pub phase: Phase,         // Layout phase
}

Usage Examples

Basic Sizing

use freya::prelude::*;

fn app() -> impl IntoElement {
    rect()
        .width(Size::px(300.0))
        .height(Size::px(200.0))
}

Responsive Sizing

fn app() -> impl IntoElement {
    rect()
        .width(Size::percentage(80.0))  // 80% of parent width
        .height(Size::fill())            // Fill available height
}

Flex Layout

fn app() -> impl IntoElement {
    rect()
        .horizontal()
        .child(
            rect()
                .width(Size::flex(1.0))  // Takes 1/3 of space
                .height(Size::px(100.0))
        )
        .child(
            rect()
                .width(Size::flex(2.0))  // Takes 2/3 of space
                .height(Size::px(100.0))
        )
}

Content-Based Sizing

fn app() -> impl IntoElement {
    rect()
        .width(Size::inner())  // Auto-size based on content
        .height(Size::inner())
        .child(text("Content"))
}

Mixed Sizing

fn app() -> impl IntoElement {
    rect()
        .expanded()  // Fill available space
        .child(
            rect()
                .width(Size::px(200.0))
                .height(Size::fill_minimum())
        )
}

Convenience Methods

Elements provide shorthand methods for common sizes:
use freya::prelude::*;

rect()
    .expanded()     // width and height = Size::fill()
    .width(100.0)   // Accepts f32, converts to Size::px()
    .height(100.0)

Size Constraints

Combine sizes with min/max constraints:
fn app() -> impl IntoElement {
    rect()
        .width(Size::percentage(50.0))
        .min_width(Size::px(200.0))
        .max_width(Size::px(600.0))
        .height(Size::fill())
        .min_height(Size::px(100.0))
}

Length Type

Length is a wrapper around f32 used by Size variants:
use torin::geometry::Length;

let length = Length::new(100.0);
let value = length.get(); // 100.0

Pretty Printing

Sizes have human-readable string representations:
let size = Size::px(100.0);
println!("{}", size.pretty()); // "100"

let size = Size::percentage(50.0);
println!("{}", size.pretty()); // "50%"

let size = Size::fill();
println!("{}", size.pretty()); // "fill"

let size = Size::inner();
println!("{}", size.pretty()); // "auto"

See Also

Build docs developers (and LLMs) love