waterui_layout/containers/spacer.rs
1//! Flexible layout gaps used by stacks and other containers.
2
3use waterui_core::raw_view;
4
5use crate::StretchAxis;
6
7/// A flexible space that expands to push views apart.
8///
9/// Spacer adapts to its parent container: in `HStack` it expands horizontally,
10/// in `VStack` it expands vertically. Use it to push views to opposite edges
11/// or distribute space evenly.
12///
13/// # Layout Behavior
14///
15/// - **In `HStack`:** Expands horizontally only
16/// - **In `VStack`:** Expands vertically only
17/// - **In `ZStack`:** Claims nothing
18///
19/// # Examples
20///
21/// ```rust
22/// use waterui::layout::spacer::spacer_min;
23/// use waterui::prelude::*;
24///
25/// // Push button to trailing edge
26/// hstack((
27/// text("Title"),
28/// spacer(),
29/// button("Done").action(|| {}),
30/// ));
31///
32/// // Center content with equal spacing
33/// hstack((spacer(), text("Centered"), spacer()));
34///
35/// // Spacer with minimum length (never shrinks below 20pt)
36/// spacer_min(20.0);
37/// ```
38#[derive(Debug, Clone, PartialEq)]
39pub struct Spacer {
40 min_length: f32,
41}
42
43impl Spacer {
44 /// The default layout priority of a flexible gap, below ordinary content.
45 pub const DEFAULT_LAYOUT_PRIORITY: i32 = i32::MIN;
46
47 /// Creates a new spacer with the specified minimum length.
48 #[must_use]
49 pub const fn new(min_length: f32) -> Self {
50 Self { min_length }
51 }
52
53 /// Creates a spacer with zero minimum length.
54 #[must_use]
55 pub const fn flexible() -> Self {
56 Self { min_length: 0.0 }
57 }
58
59 /// The length this spacer never shrinks below along the axis it expands on.
60 ///
61 /// A backend hosting the spacer answers this on the enclosing stack's main
62 /// axis whatever the proposal (and zero on the cross axis); the stack then
63 /// keeps it as the spacer's floor under compression and hands the spacer
64 /// any surplus on top of it.
65 #[must_use]
66 pub const fn min_length(&self) -> f32 {
67 self.min_length
68 }
69}
70
71raw_view!(Spacer, StretchAxis::MainAxis);
72
73/// Creates a flexible spacer with zero minimum length.
74///
75/// This spacer will expand to fill all available space in layouts.
76#[must_use]
77pub const fn spacer() -> Spacer {
78 Spacer::flexible()
79}
80
81/// Creates a spacer with a specific minimum length.
82///
83/// This spacer will expand to fill available space but never shrink below the minimum.
84#[must_use]
85pub const fn spacer_min(min_length: f32) -> Spacer {
86 Spacer::new(min_length)
87}