fc_dioxus/components/
split_button.rs1use crate::{
3 core::{
4 assets,
5 attrs::{availability_attributes, component_attributes},
6 },
7 prelude::*,
8 theme::use_stylesheets,
9};
10const BEM: Bem = Bem::new("fc-split-btn");
11const BTN: Bem = Bem::new("fc-btn");
12
13#[component]
19pub fn SplitButton(
20 label: AccessibleName,
22 menu_label: AccessibleName,
24 #[props(default)] variant: ButtonVariant,
25 #[props(default)] size: ButtonSize,
26 #[props(default)] availability: Availability,
27 #[props(default)] busy: bool,
28 #[props(default)] expanded: bool,
29 #[props(default)] onclick: Option<EventHandler<MouseEvent>>,
30 #[props(default)] ontoggle: Option<EventHandler<()>>,
31 #[props(default)] menu: Option<Element>,
32 #[props(default)] class: Option<String>,
33 #[props(extends = GlobalAttributes)] attributes: Vec<Attribute>,
34 children: Element,
35) -> Element {
36 let attributes = component_attributes(
37 attributes,
38 ClassList::new(BEM.block()).extend(class.as_deref()),
39 &["role", "aria-label"],
40 );
41 let mut toggle_state = availability_attributes(&availability);
44 if busy && availability == Availability::Enabled {
45 toggle_state.push(Attribute::new("aria-disabled", "true", None, false));
46 }
47 let toggle_blocked = busy || availability != Availability::Enabled;
48 let toggle_class = ClassList::new(BTN.block())
49 .with_modifier(BTN, variant)
50 .with_modifier(BTN, size)
51 .with(BTN.modifier_raw("icon"))
52 .with(BEM.element("toggle"))
53 .to_string();
54 rsx! {
55 if use_stylesheets() {
56 document::Stylesheet { href: assets::COMPONENTS_BUTTON_CSS }
57 document::Stylesheet { href: assets::COMPONENTS_SPLIT_BUTTON_CSS }
58 }
59 div { role: "group", aria_label: label.to_string(), ..attributes,
60 Button { variant, size, availability: availability.clone(), busy, onclick, class: BEM.element("action"), {children} }
61 button { class: toggle_class, r#type: "button", aria_haspopup: "menu", aria_expanded: expanded.to_string(),
62 aria_label: menu_label.to_string(),
63 onclick: move |event| if toggle_blocked { event.prevent_default(); } else if let Some(ontoggle) = ontoggle { ontoggle.call(()); },
64 ..toggle_state,
65 span { class: BEM.element("chevron"), aria_hidden: "true" }
66 }
67 {menu}
68 }
69 }
70}