aura-gui 0.2.2

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.
//! Fila del explorador de archivos con indentación por nivel.

use crate::core::px;
use crate::view::interactivity::ClickHandler;
use crate::view::prelude::*;
use std::rc::Rc;

pub struct TreeItem {
    label: String,
    depth: usize,
    expanded: Option<bool>,
    selected: bool,
    id: Option<String>,
    on_click: Option<ClickHandler>,
}

impl TreeItem {
    pub fn new(label: impl Into<String>) -> Self {
        Self { label: label.into(), depth: 0, expanded: None, selected: false, id: None, on_click: None }
    }

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

    /// `Some(estado)` marca una carpeta; `None` es un archivo.
    pub fn expanded(mut self, expanded: Option<bool>) -> Self {
        self.expanded = expanded;
        self
    }

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

    pub fn id(mut self, id: impl Into<String>) -> Self {
        self.id = Some(id.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 TreeItem {
    fn into_element(self) -> AnyElement {
        let marker = match self.expanded {
            Some(true) => "v",
            Some(false) => ">",
            None => " ",
        };
        let handler = self.on_click.clone();
        div()
            .flex_row()
            .items_center()
            .gap_1()
            .w_full()
            .h(px(24.0))
            .flex_shrink_0()
            .pl_for_depth(self.depth)
            .text_sm()
            .text_color(if self.selected { Token::Text } else { Token::TextMuted })
            .when(self.selected, |row| row.bg(Token::Selection))
            .hover(|style| style.bg(Token::Hover))
            .when_some(self.id, |row, id| row.id(id))
            .when_some(handler, |row, handler| row.on_click(move |event, cx| handler(event, cx)))
            .child(div().w(px(12.0)).text_xs().child(marker))
            .child(self.label)
            .into_element()
    }
}

trait DepthPadding {
    fn pl_for_depth(self, depth: usize) -> Self;
}

impl DepthPadding for Div {
    fn pl_for_depth(mut self, depth: usize) -> Self {
        self.style().padding.left = Some(px(8.0 + depth as f32 * 12.0));
        self
    }
}