patternfly_yew/components/
list.rs1use crate::icon::Icon;
3use crate::prelude::{AsClasses, ExtendClasses};
4use crate::utils::Raw;
5use yew::html::ChildrenRenderer;
6use yew::virtual_dom::VChild;
7use yew::{html::IntoPropValue, prelude::*, virtual_dom::AttrValue};
8
9#[derive(Copy, Clone, PartialEq, Eq)]
10pub enum ListType {
11 Basic,
12 Inline,
13 Ordered(ListOrder),
14 Plain,
15 Bordered,
16}
17
18impl AsClasses for ListType {
19 fn extend_classes(&self, classes: &mut Classes) {
20 match self {
21 ListType::Inline => {
22 classes.push(classes!("pf-m-inline"));
23 }
24 ListType::Plain => {
25 classes.push(classes!("pf-m-plain"));
26 }
27 ListType::Bordered => {
28 classes.push(classes!("pf-m-plain", "pf-m-bordered"));
29 }
30 _ => {}
31 }
32 }
33}
34
35impl Default for ListType {
36 fn default() -> Self {
37 Self::Basic
38 }
39}
40
41#[derive(Copy, Clone, Default, PartialEq, Eq)]
42pub enum ListOrder {
43 #[default]
44 Number,
45 LowercaseLetter,
46 UppercaseLetter,
47 LowercaseRomanNumber,
48 UppercaseRomanNumber,
49}
50
51impl IntoPropValue<Option<AttrValue>> for ListOrder {
52 fn into_prop_value(self) -> Option<AttrValue> {
53 Some(AttrValue::Static(match self {
54 Self::Number => "1",
55 Self::LowercaseLetter => "a",
56 Self::UppercaseLetter => "A",
57 Self::LowercaseRomanNumber => "i",
58 Self::UppercaseRomanNumber => "I",
59 }))
60 }
61}
62
63#[derive(PartialEq, Properties)]
65pub struct ListProperties {
66 #[prop_or_default]
67 pub children: ChildrenRenderer<ListChildVariant>,
68 #[prop_or_default]
69 pub r#type: ListType,
70 #[prop_or_default]
71 pub icon_size: ListIconSize,
72}
73
74#[derive(Clone, Copy, Default, Eq, PartialEq, Debug)]
75pub enum ListIconSize {
76 #[default]
77 Default,
78 Large,
79}
80
81impl AsClasses for ListIconSize {
82 fn extend_classes(&self, classes: &mut Classes) {
83 match self {
84 Self::Default => {}
85 Self::Large => classes.extend(classes!("pf-m-icon-lg")),
86 }
87 }
88}
89
90#[function_component(List)]
125pub fn list(props: &ListProperties) -> Html {
126 let mut classes = Classes::from("pf-v5-c-list");
127
128 classes.extend_from(&props.r#type);
129 classes.extend_from(&props.icon_size);
130
131 let l = |items| match props.r#type {
132 ListType::Basic | ListType::Inline | ListType::Plain | ListType::Bordered => {
133 html! (<ul class={classes} role="list">{ items }</ul>)
134 }
135 ListType::Ordered(n) => {
136 html! (<ol type={n} class={classes} role="list">{ items }</ol>)
137 }
138 };
139
140 l(html! ({
141 for props.children.clone()
142 }))
143}
144
145#[derive(PartialEq, Properties)]
146pub struct ListItemProperties {
147 #[prop_or_default]
148 pub children: Html,
149 #[prop_or_default]
150 pub icon: Option<Icon>,
151}
152
153#[function_component(ListItem)]
154pub fn list_item(props: &ListItemProperties) -> Html {
155 match props.icon {
156 Some(icon) => {
157 let class = classes!("pf-v5-c-list__item");
158 html!(
159 <li {class}>
160 <span class={classes!("pf-v5-c-list__item-icon")}>
161 { icon }
162 </span>
163 <span class={classes!("pf-v5-c-list__item-text")}>
164 { props.children.clone() }
165 </span>
166 </li>
167 )
168 }
169 None => html!( <li> { props.children.clone() } </li> ),
170 }
171}
172
173#[derive(Clone, PartialEq)]
174pub enum ListChildVariant {
175 Item(VChild<ListItem>),
176 Raw(VChild<Raw>),
177}
178
179impl From<VChild<ListItem>> for ListChildVariant {
180 fn from(value: VChild<ListItem>) -> Self {
181 Self::Item(value)
182 }
183}
184
185impl From<VChild<Raw>> for ListChildVariant {
186 fn from(value: VChild<Raw>) -> Self {
187 Self::Raw(value)
188 }
189}
190
191impl From<ListChildVariant> for Html {
192 fn from(value: ListChildVariant) -> Self {
193 match value {
194 ListChildVariant::Item(child) => child.into(),
195 ListChildVariant::Raw(child) => child.into(),
196 }
197 }
198}