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! ({
136 for props.children.clone()
137 }))
138}
139
140#[derive(PartialEq, Properties)]
141pub struct ListItemProperties {
142 #[prop_or_default]
143 pub children: Html,
144 #[prop_or_default]
145 pub icon: Option<Icon>,
146}
147
148#[function_component(ListItem)]
149pub fn list_item(props: &ListItemProperties) -> Html {
150 match props.icon {
151 Some(icon) => {
152 let class = classes!("pf-v6-c-list__item");
153 html!(
154 <li {class}>
155 <span class={classes!("pf-v6-c-list__item-icon")}>
156 { icon }
157 </span>
158 <span class={classes!("pf-v6-c-list__item-text")}>
159 { props.children.clone() }
160 </span>
161 </li>
162 )
163 }
164 None => html!( <li> { props.children.clone() } </li> ),
165 }
166}
167
168#[derive(Clone, PartialEq)]
169pub enum ListChildVariant {
170 Item(VChild<ListItem>),
171 Raw(VChild<Raw>),
172}
173
174impl From<VChild<ListItem>> for ListChildVariant {
175 fn from(value: VChild<ListItem>) -> Self {
176 Self::Item(value)
177 }
178}
179
180impl From<VChild<Raw>> for ListChildVariant {
181 fn from(value: VChild<Raw>) -> Self {
182 Self::Raw(value)
183 }
184}
185
186impl From<ListChildVariant> for Html {
187 fn from(value: ListChildVariant) -> Self {
188 match value {
189 ListChildVariant::Item(child) => child.into(),
190 ListChildVariant::Raw(child) => child.into(),
191 }
192 }
193}