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 full_height: bool,
72 #[prop_or_default]
74 pub plain: bool,
75 #[prop_or_default]
77 pub expanded: bool,
78 #[prop_or_default]
80 pub style: Option<AttrValue>,
81
82 #[prop_or_default]
84 pub ouia_id: Option<String>,
85 #[prop_or(OUIA.component_type())]
87 pub ouia_type: OuiaComponentType,
88 #[prop_or(OuiaSafe::TRUE)]
90 pub ouia_safe: OuiaSafe,
91}
92
93#[derive(Debug, Clone, PartialEq)]
94struct CardContext {
95 card_id: AttrValue,
96 expanded: bool,
97 clickable: bool,
98 selectable: bool,
99 disabled: bool,
100}
101
102#[function_component(Card)]
136pub fn card(props: &CardProperties) -> Html {
137 let ouia_id = use_memo(props.ouia_id.clone(), |id| {
138 id.clone().unwrap_or(OUIA.generated_id())
139 });
140 let mut class = classes!("pf-v6-c-card");
141
142 if props.size == CardSize::Compact {
143 class.push("pf-m-compact");
144 }
145 if props.size == CardSize::Large {
146 class.push("pf-m-display-lg");
147 }
148 if props.disabled {
149 class.push("pf-m-disabled");
150 }
151 if props.expanded {
152 class.push("pf-m-expanded");
153 }
154 if props.flat {
155 class.push("pf-m-flat");
156 }
157 if props.selectable {
158 class.push("pf-m-selectable")
159 }
160 if props.selected {
161 class.push("pf-m-selected")
162 }
163 if props.full_height {
164 class.push("pf-m-full-height");
165 }
166 if props.plain {
167 class.push("pf-m-plain");
168 }
169 if props.selectable && props.clickable {
170 class.push("pf-m-selectable");
171 class.push("pf-m-clickable");
172 if props.selected {
173 class.push("pf-m-current");
174 }
175 } else if props.selectable {
176 class.push("pf-m-selectable");
177 if props.selected {
178 class.push("pf-m-selected");
179 }
180 } else if props.clickable {
181 class.push("pf-m-clickable");
182 if props.selected {
183 class.push("pf-m-selected");
184 }
185 }
186 class.extend(props.class.clone());
187
188 let context = CardContext {
189 card_id: props.id.clone(),
190 expanded: props.expanded,
191 clickable: props.clickable,
192 selectable: props.selectable,
193 disabled: props.disabled,
194 };
195
196 html! (
197 <ContextProvider<CardContext> {context}>
198 <@{props.component.clone()}
199 id={props.id.clone()}
200 {class}
201 style={props.style.clone()}
202 data-ouia-component-id={(*ouia_id).clone()}
203 data-ouia-component-type={props.ouia_type}
204 data-ouia-safe={props.ouia_safe}
205 >
206 {props.children.clone()}
207 </@>
208 </ContextProvider<CardContext>>
209 )
210}
211
212#[function_component(CardDivider)]
220pub fn card_divider() -> Html {
221 html!(<Divider r#type={DividerType::Hr} />)
222}