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