patternfly_yew/components/card/
mod.rs1use crate::prelude::{Divider, DividerType, OuiaComponentType};
2use crate::utils::{Ouia, OuiaSafe};
3use yew::prelude::*;
4
5const OUIA: Ouia = ouia!("Card");
6
7mod actions;
8mod body;
9mod expandable_content;
10mod footer;
11mod header;
12mod selectable_actions;
13mod title;
14
15use crate::ouia;
16pub use actions::*;
17pub use body::*;
18pub use expandable_content::*;
19pub use footer::*;
20pub use header::*;
21pub use selectable_actions::*;
22pub use title::*;
23
24#[derive(Debug, Clone, Copy, Default, PartialEq)]
26pub enum CardSize {
27 #[default]
28 Default,
29 Compact,
30 Large,
31}
32
33#[derive(Clone, PartialEq, Properties)]
35pub struct CardProperties {
36 #[prop_or_default]
38 pub children: Html,
39 #[prop_or_default]
41 pub id: AttrValue,
42 #[prop_or_default]
44 pub class: Classes,
45 #[prop_or(String::from("div"))]
47 pub component: String,
48 #[prop_or_default]
50 pub size: CardSize,
51 #[prop_or_default]
53 pub selectable: bool,
54 #[prop_or_default]
56 pub selected: bool,
57 #[prop_or_default]
62 pub clickable: bool,
63 #[prop_or_default]
65 pub disabled: bool,
66 #[prop_or_default]
68 pub flat: bool,
69 #[prop_or_default]
71 pub rounded: bool,
72 #[prop_or_default]
74 pub full_height: bool,
75 #[prop_or_default]
77 pub plain: bool,
78 #[prop_or_default]
80 pub expanded: bool,
81 #[prop_or_default]
83 pub style: Option<AttrValue>,
84
85 #[prop_or_default]
87 pub ouia_id: Option<String>,
88 #[prop_or(OUIA.component_type())]
90 pub ouia_type: OuiaComponentType,
91 #[prop_or(OuiaSafe::TRUE)]
93 pub ouia_safe: OuiaSafe,
94}
95
96#[derive(Debug, Clone, PartialEq)]
97struct CardContext {
98 card_id: AttrValue,
99 expanded: bool,
100 clickable: bool,
101 selectable: bool,
102 disabled: bool,
103}
104
105#[function_component(Card)]
139pub fn card(props: &CardProperties) -> Html {
140 let ouia_id = use_memo(props.ouia_id.clone(), |id| {
141 id.clone().unwrap_or(OUIA.generated_id())
142 });
143 let mut class = classes!("pf-v5-c-card");
144
145 if props.size == CardSize::Compact {
146 class.push("pf-m-compact");
147 }
148 if props.size == CardSize::Large {
149 class.push("pf-m-display-lg");
150 }
151 if props.disabled {
152 class.push("pf-m-disabled");
153 }
154 if props.expanded {
155 class.push("pf-m-expanded");
156 }
157 if props.flat {
158 class.push("pf-m-flat");
159 }
160 if props.selectable {
161 class.push("pf-m-selectable")
162 }
163 if props.selected {
164 class.push("pf-m-selected")
165 }
166 if props.full_height {
167 class.push("pf-m-full-height");
168 }
169 if props.rounded {
170 class.push("pf-m-rounded");
171 }
172 if props.plain {
173 class.push("pf-m-plain");
174 }
175 if props.selectable && props.clickable {
176 class.push("pf-m-selectable");
177 class.push("pf-m-clickable");
178 if props.selected {
179 class.push("pf-m-current");
180 }
181 } else if props.selectable {
182 class.push("pf-m-selectable");
183 if props.selected {
184 class.push("pf-m-selected");
185 }
186 } else if props.clickable {
187 class.push("pf-m-clickable");
188 if props.selected {
189 class.push("pf-m-selected");
190 }
191 }
192 class.extend(props.class.clone());
193
194 let context = CardContext {
195 card_id: props.id.clone(),
196 expanded: props.expanded,
197 clickable: props.clickable,
198 selectable: props.selectable,
199 disabled: props.disabled,
200 };
201
202 html! (
203 <ContextProvider<CardContext> {context}>
204 <@{props.component.clone()}
205 id={props.id.clone()}
206 {class}
207 style={props.style.clone()}
208 data-ouia-component-id={(*ouia_id).clone()}
209 data-ouia-component-type={props.ouia_type}
210 data-ouia-safe={props.ouia_safe}
211 >
212 {props.children.clone()}
213 </@>
214 </ContextProvider<CardContext>>
215 )
216}
217
218#[function_component(CardDivider)]
226pub fn card_divider() -> Html {
227 html!(<Divider r#type={DividerType::Hr} />)
228}