A political conference and discussion platform, in Rust and Dioxus
Something went wrong. Try again.
2.6 kB · 70 lines
Rust
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071//! An M3 Expressive split button: one action, plus a menu of related ones.//!//! "Split buttons are made of a common button and a menu icon button", and the//! menu button "spins and changes shape when activated". The pairing is for a//! frequent action that has less frequent relatives — not for two equal actions,//! which is a button group.
use dioxus::prelude::*;
/// A filled action with a connected menu button beside it.////// `children` are the menu's items; give each the `split-menu-item` class (or/// use whatever markup suits — the menu is a plain surface). The menu closes on/// Escape, on losing focus, and after a click inside it, so an item does not/// have to close it itself.#[component]pub fn SplitButton( label: String, icon: String, disabled: bool, menu_label: String, on_click: EventHandler<()>, children: Element,) -> Element { let mut open = use_signal(|| false); rsx! { div { class: "m3-split", button { class: "btn btn-primary m3-split-action", r#type: "button", disabled, onclick: move |_| on_click.call(()), span { class: "material-icons", "{icon}" } " {label}" } button { class: if open() { "btn btn-primary m3-split-menu open" } else { "btn btn-primary m3-split-menu" }, r#type: "button", disabled, "aria-haspopup": "menu", "aria-expanded": if open() { "true" } else { "false" }, aria_label: "{menu_label}", onclick: move |_| { let now = open(); open.set(!now); }, span { class: "material-icons", "expand_more" } } if open() { // A click anywhere else closes it, including a click on the page // behind — without this the menu would outlive the decision. div { class: "m3-split-scrim", onclick: move |_| open.set(false), } div { class: "m3-split-sheet", role: "menu", onkeydown: move |e| { if e.key() == Key::Escape { open.set(false); } }, onclick: move |_| open.set(false), {children} } } } }}