yew_bs/components/
grid.rs1use yew::prelude::*;
2use crate::components::common::Breakpoint;
3#[derive(Properties, PartialEq)]
4pub struct GridProps {
5 #[prop_or_default]
6 pub children: Children,
7 #[prop_or_default]
8 pub fluid: bool,
9 #[prop_or_default]
10 pub breakpoint: Option<Breakpoint>,
11 #[prop_or_default]
12 pub gutter: Option<u8>,
13 #[prop_or_default]
14 pub gutter_x: Option<u8>,
15 #[prop_or_default]
16 pub gutter_y: Option<u8>,
17 #[prop_or_default]
18 pub container_class: Option<AttrValue>,
19 #[prop_or_default]
20 pub row_class: Option<AttrValue>,
21 #[prop_or_default]
22 pub node_ref: NodeRef,
23}
24#[function_component(Grid)]
25pub fn grid(props: &GridProps) -> Html {
26 let mut container_classes = Classes::new();
27 if props.fluid {
28 container_classes.push("container-fluid");
29 } else if let Some(breakpoint) = props.breakpoint {
30 container_classes.push(format!("container-{}", breakpoint.as_str()));
31 } else {
32 container_classes.push("container");
33 }
34 if let Some(class) = &props.container_class {
35 container_classes.push(class.to_string());
36 }
37 let mut row_classes = Classes::new();
38 row_classes.push("row");
39 if let Some(gutter) = props.gutter {
40 row_classes.push(format!("g-{}", gutter));
41 } else {
42 if let Some(gutter_x) = props.gutter_x {
43 row_classes.push(format!("gx-{}", gutter_x));
44 }
45 if let Some(gutter_y) = props.gutter_y {
46 row_classes.push(format!("gy-{}", gutter_y));
47 }
48 }
49 if let Some(class) = &props.row_class {
50 row_classes.push(class.to_string());
51 }
52 html! {
53 < div class = { container_classes } ref = { props.node_ref.clone() } > < div
54 class = { row_classes } > { for props.children.iter() } </ div > </ div >
55 }
56}
57#[derive(Properties, PartialEq)]
58pub struct GridItemProps {
59 #[prop_or_default]
60 pub children: Children,
61 #[prop_or_default]
62 pub size: Option<GridSize>,
63 #[prop_or_default]
64 pub xs: Option<GridSize>,
65 #[prop_or_default]
66 pub sm: Option<GridSize>,
67 #[prop_or_default]
68 pub md: Option<GridSize>,
69 #[prop_or_default]
70 pub lg: Option<GridSize>,
71 #[prop_or_default]
72 pub xl: Option<GridSize>,
73 #[prop_or_default]
74 pub xxl: Option<GridSize>,
75 #[prop_or_default]
76 pub offset: Option<u8>,
77 #[prop_or_default]
78 pub order: Option<GridOrder>,
79 #[prop_or_default]
80 pub class: Option<AttrValue>,
81 #[prop_or_default]
82 pub node_ref: NodeRef,
83}
84#[derive(Clone, Copy, PartialEq, Debug)]
85pub enum GridSize {
86 Auto,
87 Fixed(u8),
88}
89#[derive(Clone, Copy, PartialEq, Debug)]
90pub enum GridOrder {
91 First,
92 Last,
93 Number(u8),
94}
95impl GridOrder {
96 pub fn as_str(&self) -> String {
97 match self {
98 GridOrder::First => "first".to_string(),
99 GridOrder::Last => "last".to_string(),
100 GridOrder::Number(n) => n.to_string(),
101 }
102 }
103}
104#[function_component(GridItem)]
105pub fn grid_item(props: &GridItemProps) -> Html {
106 let mut classes = Classes::new();
107 let has_breakpoint_sizes = props.xs.is_some() || props.sm.is_some()
108 || props.md.is_some() || props.lg.is_some() || props.xl.is_some()
109 || props.xxl.is_some();
110 if !has_breakpoint_sizes {
111 match props.size {
112 Some(GridSize::Auto) => classes.push("col-auto"),
113 Some(GridSize::Fixed(size)) => classes.push(format!("col-{}", size)),
114 None => classes.push("col"),
115 }
116 } else {
117 if let Some(size) = props.xs {
118 match size {
119 GridSize::Auto => classes.push("col-auto"),
120 GridSize::Fixed(s) => classes.push(format!("col-{}", s)),
121 }
122 }
123 if let Some(size) = props.sm {
124 match size {
125 GridSize::Auto => classes.push("col-sm-auto"),
126 GridSize::Fixed(s) => classes.push(format!("col-sm-{}", s)),
127 }
128 }
129 if let Some(size) = props.md {
130 match size {
131 GridSize::Auto => classes.push("col-md-auto"),
132 GridSize::Fixed(s) => classes.push(format!("col-md-{}", s)),
133 }
134 }
135 if let Some(size) = props.lg {
136 match size {
137 GridSize::Auto => classes.push("col-lg-auto"),
138 GridSize::Fixed(s) => classes.push(format!("col-lg-{}", s)),
139 }
140 }
141 if let Some(size) = props.xl {
142 match size {
143 GridSize::Auto => classes.push("col-xl-auto"),
144 GridSize::Fixed(s) => classes.push(format!("col-xl-{}", s)),
145 }
146 }
147 if let Some(size) = props.xxl {
148 match size {
149 GridSize::Auto => classes.push("col-xxl-auto"),
150 GridSize::Fixed(s) => classes.push(format!("col-xxl-{}", s)),
151 }
152 }
153 }
154 if let Some(offset) = props.offset {
155 classes.push(format!("offset-{}", offset));
156 }
157 if let Some(order) = &props.order {
158 classes.push(format!("order-{}", order.as_str()));
159 }
160 if let Some(class) = &props.class {
161 classes.push(class.to_string());
162 }
163 html! {
164 < div class = { classes } ref = { props.node_ref.clone() } > { for props.children
165 .iter() } </ div >
166 }
167}