1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
use yew::prelude::*;
use crate::util::Color;
use super::*;
/// The variant style of a [ListGroup]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ListGroupVariant {
/// Default style, with rounded corners and outer borders.
Default,
/// Flush style, removes rounding and border.
Flush,
}
impl Default for ListGroupVariant {
fn default() -> Self {
ListGroupVariant::Default
}
}
/// A size threshold to trigger a property at
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum SizeTrigger {
/// Trigger at the given size boundary
AtSize(ContainerSize),
/// Always active
Always,
/// Never active
Never,
}
/// # Properties of [ListGroup]
#[derive(Properties, Clone, PartialEq)]
pub struct ListGroupProps {
/// Inner items (displayed in the [ListGroup]).
#[prop_or_default]
pub children: ChildrenWithProps<ListGroupItem>,
/// Extra CSS classes to include, in addition to the defaults.
#[prop_or_default]
pub class: Classes,
/// Display variant to use, see [ListGroupVariant] for all options.
#[prop_or_default]
pub variant: ListGroupVariant,
/// Whether to number the list.
#[prop_or_default]
pub numbered: bool,
/// Control when the list is displayed horizontally. Always, or at a certain container size.
#[prop_or(SizeTrigger::Never)]
pub horizontal: SizeTrigger,
}
/// # ListGroup component
/// A list of items with various properties, including support for numbering, actions, and item
/// colors.
///
/// Items are expected to be instances of [ListGroupItem]
///
/// See [ListGroupProps] for a list of properties.
///
/// ## Example
/// Example of a simple list group:
///
/// ```rust
/// use yew::prelude::*;
/// use yew_bootstrap::component::{ListGroup, ListGroupItem};
/// fn test() -> Html {
/// html! {
/// <ListGroup>
/// <ListGroupItem>{"First"}</ListGroupItem>
/// <ListGroupItem active=true>{"Second"}</ListGroupItem>
/// <ListGroupItem>{"Third"}</ListGroupItem>
/// </ListGroup>
/// }
/// }
///
#[function_component]
pub fn ListGroup(props: &ListGroupProps) -> Html {
let mut classes = Classes::from("list-group");
classes.extend(&props.class);
match props.variant {
ListGroupVariant::Default => (),
ListGroupVariant::Flush => classes.push("list-group-flush"),
};
match &props.horizontal {
SizeTrigger::Never => (),
SizeTrigger::Always => classes.push("list-group-horizontal"),
SizeTrigger::AtSize(size) => classes.push(format!("list-group-horizontal-{}", size.to_string())),
}
if props.numbered {
classes.push("list-group-numbered")
}
html! {
<div class={classes}>
{ for props.children.iter() }
</div>
}
}
/// # Properties for [ListGroupItem]
#[derive(Properties, Clone, PartialEq)]
pub struct ListGroupItemProps {
/// Inner components (displayed in the [ListGroupItem]).
#[prop_or_default]
pub children: Children,
/// Extra CSS classes to include, in addition to the defaults.
#[prop_or_default]
pub class: Classes,
/// Optional color to use for the background and border of this item.
#[prop_or_default]
pub style: Option<Color>,
/// Whether this item is the currently active one
#[prop_or_default]
pub active: bool,
/// Whether this item is disabled
#[prop_or_default]
pub disabled: bool,
/// Whether this item is actionable, enables hover and click reactivity.
#[prop_or_default]
pub action: bool,
/// URL to direct to when the list item is clicked
#[prop_or_default]
pub url: Option<AttrValue>,
/// Event called when the list item is clicked
#[prop_or_default]
pub onclick: Callback<MouseEvent>,
}
/// # ListGroupItem
/// Used with [ListGroup] to create grouped lists of items.
///
/// See [ListGroupItemProps] for a list of properties.
///
/// ## Example
/// Example of a simple list group:
///
/// ```rust
/// use yew::prelude::*;
/// use yew_bootstrap::component::{ListGroup, ListGroupItem};
/// use yew_bootstrap::util::Color;
/// fn test() -> Html {
/// html! {
/// <ListGroup>
/// <ListGroupItem style={Color::Light}>{"First"}</ListGroupItem>
/// <ListGroupItem active=true>{"Second"}</ListGroupItem>
/// <ListGroupItem disabled=true>{"Third"}</ListGroupItem>
/// </ListGroup>
/// }
/// }
///
#[function_component]
pub fn ListGroupItem(props: &ListGroupItemProps) -> Html {
let mut classes = Classes::from("list-group-item");
classes.extend(&props.class);
if props.active {
classes.push("active");
}
if props.disabled {
classes.push("disabled");
}
if let Some(style) = &props.style {
classes.push(format!("list-group-item-{}", style));
}
if props.action && props.url.is_some() {
classes.push("list-group-item-action");
html! {
<a class={classes} href={&props.url} onclick={props.onclick.clone()}>
{props.children.clone()}
</a>
}
} else if props.action {
classes.push("list-group-item-action");
html! {
<button class={classes} onclick={props.onclick.clone()}>
{props.children.clone()}
</button>
}
} else {
html! {
<div class={classes}>
{props.children.clone()}
</div>
}
}
}