Skip to main content

cranpose_ui/widgets/
flow_row.rs

1//! FlowRow widget implementation
2
3use cranpose_core::NodeId;
4
5use super::layout::Layout;
6use crate::{composable, layout::policies::FlowRowMeasurePolicy, modifier::Modifier};
7
8/// Specification for FlowRow layout behavior.
9#[derive(Clone, Copy, Debug, PartialEq)]
10pub struct FlowRowSpec {
11    /// Horizontal gap between adjacent children on the same line, in dp
12    /// (Compose: `horizontalArrangement = Arrangement.spacedBy(..)`).
13    pub main_axis_spacing: f32,
14    /// Vertical gap between consecutive lines, in dp
15    /// (Compose: `verticalArrangement = Arrangement.spacedBy(..)`).
16    pub cross_axis_spacing: f32,
17}
18
19impl FlowRowSpec {
20    pub fn new() -> Self {
21        Self::default()
22    }
23
24    pub fn main_axis_spacing(mut self, spacing: f32) -> Self {
25        self.main_axis_spacing = spacing;
26        self
27    }
28
29    pub fn cross_axis_spacing(mut self, spacing: f32) -> Self {
30        self.cross_axis_spacing = spacing;
31        self
32    }
33}
34
35impl Default for FlowRowSpec {
36    fn default() -> Self {
37        Self {
38            main_axis_spacing: 0.0,
39            cross_axis_spacing: 0.0,
40        }
41    }
42}
43
44/// A layout composable that places its children in horizontal sequence and
45/// wraps to the next line when it runs out of width (Jetpack Compose's
46/// `FlowRow`).
47///
48/// # When to use
49/// Use `FlowRow` for content whose item count or widths vary — chip groups,
50/// tag clouds, toolbars on narrow screens. For a single non-wrapping line,
51/// use [`Row`](crate::widgets::Row).
52///
53/// # Arguments
54///
55/// * `modifier` - Modifiers to apply to the flow layout.
56/// * `spec` - Spacing between items on a line and between lines.
57/// * `content` - The children composables to layout.
58///
59/// # Example
60///
61/// ```rust,ignore
62/// FlowRow(
63///     Modifier::fill_max_width(),
64///     FlowRowSpec::new().main_axis_spacing(8.0).cross_axis_spacing(4.0),
65///     || {
66///         for label in ["Rust", "Compose", "Android"] {
67///             Chip(label);
68///         }
69///     },
70/// );
71/// ```
72#[composable]
73pub fn FlowRow<F>(modifier: Modifier, spec: FlowRowSpec, content: F) -> NodeId
74where
75    F: FnMut() + 'static,
76{
77    let policy = FlowRowMeasurePolicy::new(spec.main_axis_spacing, spec.cross_axis_spacing);
78    Layout(modifier, policy, content)
79}