aura-gui 0.3.5

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.
//! Etiqueta compacta para estados y contadores, y el `chip` pulsable para filtros y formatos.

use crate::core::px;
use crate::view::prelude::*;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BadgeVariant {
    Default,
    Accent,
    Danger,
    Outline,
}

pub struct Badge {
    label: String,
    variant: BadgeVariant,
    style: Style,
}

impl Badge {
    pub fn new(label: impl Into<String>) -> Self {
        Self { label: label.into(), variant: BadgeVariant::Default, style: Style::default() }
    }

    pub fn variant(mut self, variant: BadgeVariant) -> Self {
        self.variant = variant;
        self
    }
}

impl Styled for Badge {
    fn style(&mut self) -> &mut Style {
        &mut self.style
    }
}

impl IntoElement for Badge {
    fn into_element(self) -> AnyElement {
        let (background, foreground) = match self.variant {
            BadgeVariant::Default => (Some(Token::Active), Token::Text),
            BadgeVariant::Accent => (Some(Token::Accent), Token::AccentText),
            BadgeVariant::Danger => (Some(Token::Danger), Token::DangerText),
            BadgeVariant::Outline => (None, Token::TextMuted),
        };
        div()
            .flex_row()
            .items_center()
            .px_2()
            .py(px(2.0))
            .rounded_full()
            .text_xs()
            .text_color(foreground)
            .when_some(background, |badge, color| badge.bg(color))
            .when(self.variant == BadgeVariant::Outline, |badge| badge.border_1().border_color(Token::Border))
            .refine_style(&self.style)
            .child(self.label)
            .into_element()
    }
}

/// Etiqueta redondeada y pulsable (formatos, filtros, sugerencias). AƱade `.on_click(..)` donde se use.
pub fn chip(label: impl Into<String>, selected: bool) -> Div {
    div()
        .flex_row()
        .items_center()
        .flex_shrink_0()
        .gap_1()
        .px_2()
        .py(px(3.0))
        .rounded_full()
        .border_1()
        .border_color(if selected { Token::BorderFocused } else { Token::Border })
        .bg(if selected { Token::Selection } else { Token::Surface })
        .text_xs()
        .text_color(if selected { Token::Text } else { Token::TextMuted })
        .cursor_pointer()
        .hover(|style| style.bg(Token::Hover))
        .child(label.into())
}