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.
//! Métodos de `Div` para el puntero: forma del cursor, grupos de hover y arrastrar/soltar.

use crate::core::CursorStyle;
use crate::view::any_element::AnyElement;
use crate::view::div::Div;
use crate::view::drag::{DragSource, DropTarget};
use crate::view::interactivity::EventContext;
use crate::view::style::Style;
use crate::view::styled::Styled;
use crate::view::theme::Token;
use std::any::{Any, TypeId};
use std::rc::Rc;

impl Div {
    pub fn cursor(mut self, cursor: CursorStyle) -> Self {
        self.interactivity.cursor = Some(cursor);
        self
    }

    /// Mano: el elemento se puede pulsar (como `cursor-pointer` de Tailwind).
    pub fn cursor_pointer(self) -> Self {
        self.cursor(CursorStyle::PointingHand)
    }

    /// Lo que hace que un elemento «se sienta» pulsable: mano, y fondo `Hover` al pasar el puntero y `Active` al pulsar.
    pub fn pressable(self) -> Self {
        self.cursor_pointer().hover(|style| style.bg(Token::Hover)).active(|style| style.bg(Token::Active))
    }

    /// Como [`Div::pressable`], o, si `enabled` es `false`, sin resalte y a 35 % de opacidad (deshabilitado).
    pub fn pressable_if(self, enabled: bool) -> Self {
        if enabled { self.pressable() } else { self.opacity(0.35) }
    }

    pub fn cursor_text(self) -> Self {
        self.cursor(CursorStyle::IBeam)
    }

    pub fn cursor_col_resize(self) -> Self {
        self.cursor(CursorStyle::ResizeColumn)
    }

    pub fn cursor_row_resize(self) -> Self {
        self.cursor(CursorStyle::ResizeRow)
    }

    /// Nombra este elemento como grupo (como `group` de Tailwind).
    pub fn group(mut self, name: &str) -> Self {
        self.interactivity.group = Some(Rc::from(name));
        self
    }

    /// Estilo extra mientras el puntero está sobre el grupo `name` (como `group-hover:`).
    pub fn group_hover(mut self, name: &str, refine: impl FnOnce(Style) -> Style) -> Self {
        self.interactivity.group_hover = Some((Rc::from(name), refine(Style::default())));
        self
    }

    /// Hace el elemento arrastrable con `value` como carga; `preview` dibuja lo que
    /// sigue al puntero. No confundir con `on_drag`, que recibe el movimiento crudo.
    pub fn draggable<T: Any>(mut self, value: T, preview: impl Fn(&T) -> AnyElement + 'static) -> Self {
        self.interactivity.drag = Some(DragSource::new(value, preview));
        self
    }

    /// Acepta cargas de tipo `T` soltadas encima.
    pub fn on_drop<T: Any>(mut self, handler: impl Fn(&T, &mut EventContext) + 'static) -> Self {
        self.interactivity.drops.push(DropTarget::new(handler));
        self
    }

    /// Estilo mientras se arrastra encima una carga de tipo `T`.
    pub fn drag_over<T: Any>(mut self, refine: impl FnOnce(Style) -> Style) -> Self {
        self.interactivity.drag_over.push((TypeId::of::<T>(), refine(Style::default())));
        self
    }

    /// Rol del elemento para tecnologías de asistencia (botón, pestaña, campo…).
    pub fn role(mut self, role: accesskit::Role) -> Self {
        self.interactivity.role = Some(role);
        self
    }

    /// Nombre que el lector de pantalla anuncia para este elemento.
    pub fn label(mut self, label: impl Into<String>) -> Self {
        let label: String = label.into();
        self.interactivity.label = Some(Rc::from(label));
        self
    }
}