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}