yew_bs/components/
flex.rs

1use yew::prelude::*;
2use crate::components::common::Breakpoint;
3#[derive(Clone, Copy, PartialEq, Debug)]
4pub enum FlexDirection {
5    Row,
6    Column,
7    RowReverse,
8    ColumnReverse,
9}
10impl FlexDirection {
11    pub fn as_str(&self) -> &'static str {
12        match self {
13            FlexDirection::Row => "flex-row",
14            FlexDirection::Column => "flex-column",
15            FlexDirection::RowReverse => "flex-row-reverse",
16            FlexDirection::ColumnReverse => "flex-column-reverse",
17        }
18    }
19}
20/// Justify content values
21#[derive(Clone, Copy, PartialEq, Debug)]
22pub enum JustifyContent {
23    Start,
24    End,
25    Center,
26    Between,
27    Around,
28    Evenly,
29}
30impl JustifyContent {
31    pub fn as_str(&self) -> &'static str {
32        match self {
33            JustifyContent::Start => "justify-content-start",
34            JustifyContent::End => "justify-content-end",
35            JustifyContent::Center => "justify-content-center",
36            JustifyContent::Between => "justify-content-between",
37            JustifyContent::Around => "justify-content-around",
38            JustifyContent::Evenly => "justify-content-evenly",
39        }
40    }
41}
42#[derive(Clone, Copy, PartialEq, Debug)]
43pub enum AlignItems {
44    Start,
45    End,
46    Center,
47    Baseline,
48    Stretch,
49}
50impl AlignItems {
51    pub fn as_str(&self) -> &'static str {
52        match self {
53            AlignItems::Start => "align-items-start",
54            AlignItems::End => "align-items-end",
55            AlignItems::Center => "align-items-center",
56            AlignItems::Baseline => "align-items-baseline",
57            AlignItems::Stretch => "align-items-stretch",
58        }
59    }
60}
61/// Align self values (for individual flex items)
62#[derive(Clone, Copy, PartialEq, Debug)]
63pub enum AlignSelf {
64    Start,
65    End,
66    Center,
67    Baseline,
68    Stretch,
69    Auto,
70}
71impl AlignSelf {
72    pub fn as_str(&self) -> &'static str {
73        match self {
74            AlignSelf::Start => "align-self-start",
75            AlignSelf::End => "align-self-end",
76            AlignSelf::Center => "align-self-center",
77            AlignSelf::Baseline => "align-self-baseline",
78            AlignSelf::Stretch => "align-self-stretch",
79            AlignSelf::Auto => "align-self-auto",
80        }
81    }
82}
83#[derive(Clone, Copy, PartialEq, Debug)]
84pub enum FlexWrap {
85    Wrap,
86    Nowrap,
87    WrapReverse,
88}
89impl FlexWrap {
90    pub fn as_str(&self) -> &'static str {
91        match self {
92            FlexWrap::Wrap => "flex-wrap",
93            FlexWrap::Nowrap => "flex-nowrap",
94            FlexWrap::WrapReverse => "flex-wrap-reverse",
95        }
96    }
97}
98/// Flex fill utility
99#[derive(Clone, Copy, PartialEq, Debug)]
100pub enum FlexFill {
101    Fill,
102    Grow0,
103    Grow1,
104    Shrink0,
105    Shrink1,
106}
107impl FlexFill {
108    pub fn as_str(&self) -> &'static str {
109        match self {
110            FlexFill::Fill => "flex-fill",
111            FlexFill::Grow0 => "flex-grow-0",
112            FlexFill::Grow1 => "flex-grow-1",
113            FlexFill::Shrink0 => "flex-shrink-0",
114            FlexFill::Shrink1 => "flex-shrink-1",
115        }
116    }
117}
118#[derive(Properties, PartialEq)]
119pub struct FlexContainerProps {
120    #[prop_or(true)]
121    pub flex: bool,
122    #[prop_or_default]
123    pub breakpoint: Option<Breakpoint>,
124    #[prop_or_default]
125    pub direction: Option<FlexDirection>,
126    #[prop_or_default]
127    pub justify: Option<JustifyContent>,
128    #[prop_or_default]
129    pub align_items: Option<AlignItems>,
130    #[prop_or_default]
131    pub wrap: Option<FlexWrap>,
132    #[prop_or_default]
133    pub children: Children,
134    #[prop_or_default]
135    pub class: Option<AttrValue>,
136    #[prop_or("div".into())]
137    pub tag: AttrValue,
138}
139#[function_component(FlexContainer)]
140pub fn flex_container(props: &FlexContainerProps) -> Html {
141    let mut classes = Classes::new();
142    if props.flex {
143        if let Some(breakpoint) = &props.breakpoint {
144            classes.push(format!("d-{}-flex", breakpoint.as_str()));
145        } else {
146            classes.push("d-flex");
147        }
148    }
149    if let Some(direction) = &props.direction {
150        classes.push(direction.as_str());
151    }
152    if let Some(justify) = &props.justify {
153        classes.push(justify.as_str());
154    }
155    if let Some(align_items) = &props.align_items {
156        classes.push(align_items.as_str());
157    }
158    if let Some(wrap) = &props.wrap {
159        classes.push(wrap.as_str());
160    }
161    if let Some(custom_class) = &props.class {
162        classes.push(custom_class.to_string());
163    }
164    let tag = props.tag.clone();
165    html! {
166        <@ { tag.to_string() } class = { classes } > { for props.children.iter() } </@>
167    }
168}
169#[derive(Properties, PartialEq)]
170pub struct FlexItemProps {
171    #[prop_or_default]
172    pub align_self: Option<AlignSelf>,
173    #[prop_or_default]
174    pub fill: Option<FlexFill>,
175    #[prop_or_default]
176    pub children: Children,
177    #[prop_or_default]
178    pub class: Option<AttrValue>,
179    #[prop_or("div".into())]
180    pub tag: AttrValue,
181}
182#[function_component(FlexItem)]
183pub fn flex_item(props: &FlexItemProps) -> Html {
184    let mut classes = Classes::new();
185    if let Some(align_self) = &props.align_self {
186        classes.push(align_self.as_str());
187    }
188    if let Some(fill) = &props.fill {
189        classes.push(fill.as_str());
190    }
191    if let Some(custom_class) = &props.class {
192        classes.push(custom_class.to_string());
193    }
194    let tag = props.tag.clone();
195    html! {
196        <@ { tag.to_string() } class = { classes } > { for props.children.iter() } </@>
197    }
198}