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#[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#[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#[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}