aura-gui 0.1.0

UI nativa acelerada por GPU para escritorio, Android e iOS, en un solo crate: estilo tipo Tailwind, componentes, sombras, animaciones y agentes de IA. Reposo a cero. Licencia AGPL-3.0 o comercial.
//! Botón de solo icono, con estado conmutado opcional (opciones de búsqueda, paneles).

use crate::widgets::icons::{IconName, icon};
use crate::core::px;
use crate::view::interactivity::ClickHandler;
use crate::view::prelude::*;
use std::rc::Rc;

pub struct IconButton {
    icon: IconName,
    selected: bool,
    tooltip: Option<String>,
    on_click: Option<ClickHandler>,
}

impl IconButton {
    pub fn new(icon: IconName) -> Self {
        Self { icon, selected: false, tooltip: None, on_click: None }
    }

    /// Estilo de "activado", para usarlo como interruptor.
    pub fn selected(mut self, selected: bool) -> Self {
        self.selected = selected;
        self
    }

    pub fn tooltip(mut self, text: impl Into<String>) -> Self {
        self.tooltip = Some(text.into());
        self
    }

    pub fn on_click(mut self, handler: impl Fn(&ClickEvent, &mut EventContext) + 'static) -> Self {
        self.on_click = Some(Rc::new(handler));
        self
    }
}

impl IntoElement for IconButton {
    fn into_element(self) -> AnyElement {
        let handler = self.on_click.clone();
        div()
            .role(Role::Button)
            .label(self.tooltip.clone().unwrap_or_default())
            .flex_row()
            .items_center()
            .justify_center()
            .size(px(24.0))
            .flex_shrink_0()
            .rounded_md()
            .text_color(if self.selected { Token::AccentText } else { Token::TextMuted })
            .when(self.selected, |button| button.bg(Token::Accent))
            .hover(|style| style.bg(Token::Hover).text_color(Token::Text))
            .when_some(handler, |button, handler| button.cursor_pointer().on_click(move |event, cx| handler(event, cx)))
            .when_some(self.tooltip, |button, text| button.tooltip(text))
            .child(icon(self.icon).size(px(14.0)))
            .into_element()
    }
}