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