yew_layout/
row.rs

1use crate::*;
2use css_style::{
3    box_align::*, flexbox::*, prelude::*, size, Background, Border, Display, FlexDirection,
4};
5use yew::prelude::*;
6
7// ======================== Row Component ========================
8
9/// Row properties.
10///
11/// Here you can find all properties that can be used with
12/// [Row](crate::row::Row) component.
13#[derive(Properties, Clone, PartialEq)]
14pub struct Props {
15    pub children: Children,
16
17    /// Control the length of the Row
18    ///
19    /// The default is `Length::from(1.0)`
20    #[prop_or(Some(size::Length::from(1.0)))]
21    pub length: Option<Length>,
22
23    /// Control the minimum length of the Row
24    ///
25    /// The default is `Length::MinContent`
26    #[prop_or(Some(size::Length::MinContent))]
27    pub min_length: Option<Length>,
28
29    /// Control the maximum length of the Row
30    ///
31    /// The default is `None`
32    #[prop_or_default]
33    pub max_length: Option<Length>,
34
35    /// Control the width of the Row
36    ///
37    /// The default is `None`
38    #[prop_or_default]
39    pub width: Option<Length>,
40
41    /// Control the minimum width of the Row
42    ///
43    /// The default is `Length::MinContent`
44    #[prop_or(Some(size::Length::MinContent))]
45    pub min_width: Option<Length>,
46
47    /// Control the maximum width of the Row
48    ///
49    /// The default is `None`
50    #[prop_or_default]
51    pub max_width: Option<Length>,
52
53    /// Expand factor used to expand this row in direction relevant to it's
54    /// parent layout direction.
55    ///
56    /// When the parent is `Row` it will expand horizontally, when the parent is
57    /// `Column` it will expand vertically.
58    ///
59    /// Note: This only works when this `Row` inside another layout (e.g. Row/Column).
60    ///
61    /// The default is `None`
62    #[prop_or_default]
63    pub expand_by: Option<f32>,
64
65    /// Shrink factor used to shrink this row in direction relevant to it's
66    /// parent layout direction when needed.
67    ///
68    /// When the parent is `Row` it will shrink horizontally, when the parent is
69    /// `Column` it will shrink vertically.
70    ///
71    /// Note: This only works when this `Row` inside another layout (e.g. Row/Column).
72    ///
73    /// The default is `None`
74    #[prop_or_default]
75    pub shrink_by: Option<f32>,
76
77    /// Make this layout inline
78    ///
79    /// The default is `false`
80    #[prop_or(false)]
81    pub inline: bool,
82
83    /// Reverse the order of the children
84    ///
85    /// The default is `false`
86    #[prop_or(false)]
87    pub reverse: bool,
88
89    /// Wrap into another row when there is no more horizontal space.
90    ///
91    /// The default is `false`
92    #[prop_or(false)]
93    pub wrap: bool,
94
95    /// Align the children inside this row in main direction (vertically).
96    ///
97    /// The default is `None`
98    #[prop_or_default]
99    pub align: Option<Align>,
100
101    /// Align the children inside this row in the cross direction
102    /// (horizontally).
103    ///
104    /// The default is `None`
105    #[prop_or_default]
106    pub cross_align: Option<CrossAlign>,
107
108    /// Align this row when it's inside another layout, the alignment direction
109    /// is relevant to the parent layout direction
110    ///
111    /// When the parent is `Row` it will align horizontally, when the parent is
112    /// `Column` it will align vertically.
113    ///
114    /// Note: This only works when this `Row` inside another layout (e.g. Row/Column).
115    ///
116    /// The default is `None`
117    #[prop_or_default]
118    pub align_self: Option<AlignSelf>,
119
120    /// Gap between children.
121    ///
122    /// This take `Gap` value, which can take either one value that defines the
123    /// gap for both the columns and rows (if there is any), or two values one
124    /// for rows and the other for columns.
125    ///
126    /// The default is `None`
127    #[prop_or_default]
128    pub gap: Option<Gap>,
129
130    /// Reverse rows if there is more than one column within this `Column`.
131    ///
132    /// This only works when used with `wrap=true`.
133    ///
134    /// The default is `false`
135    #[prop_or(false)]
136    pub reverse_rows: bool,
137
138    /// Align rows in the cross direction (vertically) if there is more than one
139    /// row within this `Row`.
140    ///
141    /// The default is `None`
142    #[prop_or_default]
143    pub align_rows: Option<AlignRows>,
144
145    /// Overflow behavior for this Row
146    ///
147    /// By default any child that get oversized will be visible and may overlap
148    /// with other UI components. Change this property if you like to make the
149    /// content scrollable or make the oversized hidden/cliped.
150    ///
151    /// The default is `Overflow::visible()`
152    #[prop_or(Overflow::visible())]
153    pub overflow: Overflow,
154
155    /// Padding for the `Row`
156    ///
157    /// The default is `None`
158    #[prop_or_default]
159    pub padding: Option<Padding>,
160
161    /// Margin for the `Row`
162    ///
163    /// The default is `None`
164    #[prop_or_default]
165    pub margin: Option<Margin>,
166
167    /// Background for the `Row`
168    ///
169    /// The default is `None`
170    #[prop_or_default]
171    pub background: Option<Background>,
172
173    /// Border for the `Row`
174    ///
175    /// The default is `None`
176    #[prop_or_default]
177    pub border: Option<Border>,
178
179    /// Shadow for the `Row`
180    ///
181    /// The default is `None`
182    #[prop_or_default]
183    pub shadow: Option<Shadow>,
184}
185
186/// Row layout component.
187///
188/// See [row properties docs](crate::row::Props) for more details on how to
189/// use them.
190///
191/// # Usage
192///
193/// ```rust
194/// use yew_layout::{Row, Align};
195/// # use yew::prelude::*;
196///
197/// # fn view() -> Html {
198/// html! {
199///     <Row align={ Align::Center } wrap=true>
200///         { "Row children.." }
201///     </Row>
202/// }
203/// # }
204/// ```
205#[function_component(Row)]
206pub fn row(props: &Props) -> Html {
207    let style = Style::default()
208        .display(match props.inline {
209            true => Display::InlineFlex,
210            false => Display::Flex,
211        })
212        .and_size(|s| {
213            s.try_width(props.length.clone())
214                .try_min_width(props.min_length.clone())
215                .try_max_width(props.max_length.clone())
216                .try_height(props.width.clone())
217                .try_min_height(props.min_width.clone())
218                .try_max_height(props.max_width.clone())
219        })
220        .flex_direction(match props.reverse {
221            true => FlexDirection::RowReverse,
222            false => FlexDirection::Row,
223        })
224        .try_flex_wrap(match (props.wrap, props.reverse_rows) {
225            (true, true) => Some(Wrap::WrapReverse),
226            (true, false) => Some(Wrap::Wrap),
227            _ => None,
228        })
229        .try_justify_content(props.align)
230        .try_align_items(props.cross_align)
231        .try_align_content(props.align_rows)
232        .try_align_self(props.align_self)
233        .try_flex_grow(props.expand_by)
234        .try_flex_shrink(props.shrink_by)
235        .try_gap(props.gap.clone())
236        .try_padding(props.padding.clone())
237        .try_margin(props.margin.clone())
238        .try_background(props.background.clone())
239        .try_border(props.border.clone())
240        .try_box_shadow(props.shadow.clone())
241        .insert("box-sizing", "border-box")
242        .merge(props.overflow);
243
244    html! {
245        <div class="yew-layout-row" style={ style.to_string() }>
246            { props.children.clone() }
247        </div>
248    }
249}