Skip to main content

ui_storybook/components/primitives/
icon_button.rs

1//! `IconButton` — square icon-only button (M-UI.4 / AUT-124).
2
3use leptos::prelude::*;
4
5/// Visual variant.
6#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
7pub enum IconButtonVariant {
8    /// Quiet — transparent background, text-secondary glyph. Default.
9    #[default]
10    Ghost,
11    /// Filled neutral chip.
12    Filled,
13    /// Filled in the danger color.
14    Danger,
15}
16
17impl IconButtonVariant {
18    /// CSS class for the variant.
19    #[must_use]
20    pub fn css(self) -> &'static str {
21        match self {
22            IconButtonVariant::Ghost => "icon-btn-ghost",
23            IconButtonVariant::Filled => "icon-btn-filled",
24            IconButtonVariant::Danger => "icon-btn-danger",
25        }
26    }
27}
28
29#[component]
30pub fn IconButton(
31    /// Single glyph rendered as the button label.
32    #[prop(into)]
33    glyph: String,
34    /// Accessible label — required for screen readers since the visible
35    /// content is just a glyph.
36    #[prop(into)]
37    label: String,
38    #[prop(optional)] variant: IconButtonVariant,
39    #[prop(optional)] disabled: bool,
40    #[prop(optional)] pressed: bool,
41) -> impl IntoView {
42    let mut class = format!("icon-btn {}", variant.css());
43    if pressed {
44        class.push_str(" icon-btn-pressed");
45    }
46    view! {
47        <button class=class disabled=disabled aria-label=label aria-pressed=pressed>
48            <span aria-hidden="true">{glyph}</span>
49        </button>
50    }
51}