hefesto-widgets 0.6.1

Ratatui widgets for the Hefesto TUI toolkit: popups, scrollable lists, trees, text input and spinners
Documentation

hefesto-widgets

Crates.io License: MIT

Widgets reutilizables para interfaces TUI construidas con ratatui, orientados al ecosistema Hefesto. Proporcionan componentes modulares, stateful y configurables para construir asistentes interactivos en terminal.


Dependencias

Solo requiere ratatui ≥ 0.30.

[dependencies]
hefesto-widgets = "0.5.0"

Componentes

Popup — Popup base reutilizable

Caja de diálogo centrada con borde redondeado, título opcional, contenido multilínea y soporte para color de fondo (bg_color). Soporta modos de tamaño Fixed, Percent, Auto y Max.

use hefesto_widgets::{Popup, PopupSize};

let popup = Popup::new(Color::White)
    .title("Aviso")
    .content(vec![Line::from("Operación completada")])
    .width(PopupSize::Fixed(44));
Método clave Propósito
.title(), .border_color(), .border_type() Configuración de apariencia
.bg_color() Color de fondo de todo el popup (incluye borde)
.position(), .origin() Posicionamiento explícito
.content(), .empty_message() Contenido interno

BorderType — Estilos de borde

Plain, Rounded, Double, Thick, QuadrantInside, QuadrantOutside, None.

ChoosePopup — Lista seleccionable con filtro inline

Popup que muestra una lista de ítems (String, Style). El usuario puede navegar, seleccionar múltiples entradas (con límite opcional max_selected) y filtrar con un campo de texto integrado. Cada ítem seleccionado se marca con ✓.

| Método clave | Propósito | |---|---|---| | new(items) | Crea el popup con la lista de ítems | | .title(), .border_color(), .bg_color() | Configuración de apariencia | | .filter_placeholder(), .filter_rows() | Configuración del campo de búsqueda | | .max_selected(n) | Limita selección múltiple |

State: ChoosePopupState expone cursor, chosen_indices, show_filter, y delegados a TextInputState para el filtro.

ConfirmationPopup — Diálogo de confirmación

Popup compacto (44×9) con título, cuerpo, y dos botones (confirmar/cancelar) con fondos de color personalizables. Implementa Widget (sin estado).

use hefesto_widgets::ConfirmationPopup;

ConfirmationPopup::new()
    .title("Eliminar archivo")
    .body(vec![Line::from("¿Está seguro?")])
    .confirm_style(Style::new().bg(Color::Red).fg(Color::Black));
Método clave Propósito
.title(), .border_color(), .bg_color() Configuración de apariencia
.body(), .options() Contenido y etiquetas
.confirm_style(), .cancel_style() Estilo de botones

ThemedConfirmationPopup — Confirmación con variante semántica

Wrapping de ConfirmationPopup que asigna colores según la variante: Success, Warning, Danger o None. Recibe título y cuerpo en el constructor.

use hefesto_widgets::{ThemedConfirmationPopup, ConfirmationVariant};

ThemedConfirmationPopup::new(
    "Peligro",
    vec![Line::from("Esta operación no se puede deshacer")],
    ConfirmationVariant::Danger,
);
Método clave Propósito
.options() Etiquetas de botones
.border_type() Estilo de borde
.bg_color() Color de fondo del popup
.position() Posicionamiento explícito

TextInputPopup — Popup de entrada de texto

Popup que envuelve un TextInput para capturar texto del usuario. Hereda toda la configuración del TextInput (cursor, borde, placeholder, scroll) y del Popup (título, borde, posición, fondo).

Método Propósito
.title(), .border_color(), .bg_color() Configuración del popup
.input_bg_color() Fondo del área de texto (TextInput)
.cursor_style(), .text_style(), .placeholder() Configuración del TextInput

⚠️ Breaking change: en versiones anteriores bg_color() aplicaba fondo al TextInput. Ahora bg_color() aplica al popup y input_bg_color() al input.

SpinPopup — Indicador de progreso con spinner

Popup que muestra un spinner animado (variantes: Dots, Line, Dots2, Bounce, Pulse, Arrows, Square, Clock), un título, el comando en ejecución, líneas de salida en un ScrollList y un mensaje de finalización. Útil para operaciones asíncronas.

| Método | Descripción | |---|---|---| | .title() | Título descriptivo | | .command() | Comando que se está ejecutando | | .variant(SpinVariant) | Estilo de animación | | .output_lines() | Líneas de log a mostrar | | .max_output_rows() | Límite de líneas visibles | | .finished_msg() | Mensaje al completar (Enter) | | .bg_color() | Color de fondo del popup |

FileBrowserPopup — Navegador de archivos

Popup que presenta un explorador de directorios. Construido sobre ChoosePopup: navega entre directorios, muestra archivos con iconos (📁/📄), filtra por nombre y soporta selección múltiple. Oculta archivos ocultos (. por defecto) salvo que se active show_hidden.

Método clave Propósito
.border_color(), .border_type(), .bg_color() Configuración de apariencia
.dir_style(), .file_style(), .highlight_style() Estilo visual
.dir_icon(), .file_icon() Iconos personalizados
.max_selected(n) Límite de selección

State: FileBrowserState gestiona la navegación: navigate_to(), go_up(), enter_directory(), selected_entry(), chosen_paths(), más toda la API de filtro delegada.

ScrollList — Lista desplazable

Lista virtual con scrollbar vertical automático. Soporta tres constructores:

Constructor Uso
new(Vec<String>) Ítems simples
new_styled(Vec<(String, Style)>) Ítems con estilo individual
new_list(Vec<ListItem>) Ítems preconstruidos (árboles, indentación)

Incluye follow mode (autoscroll al final) útil para logs.

State: ScrollListState con select(), next(), previous(), last().

Tree — Árbol expandible/colapsable

Proyecta una jerarquía de TreeNode en una ScrollList plana con indentación e iconos de expandir/colapsar/hoja. Los nodos se identifican por id (entero único).

use hefesto_widgets::{Tree, TreeNode, TreeState};

let tree = Tree::new(vec![
    TreeNode {
        text: Line::from("src"),
        children: vec![TreeNode { text: Line::from("main.rs"), children: vec![], id: 2 }],
        id: 1,
    },
]);

// toggle expand/colapse
state.toggle(node_id);

State: TreeState con expanded: HashSet<usize>, toggle(), visible_index_of().

TextInput — Campo de texto stateful

Editor de una o varias líneas con cursor visible, placeholder, scroll horizontal automático y borde configurable. Ideal para formularios inline o filtros.

use hefesto_widgets::{TextInput, TextInputState};

let input = TextInput::new()
    .placeholder("Buscar...")
    .rows(1);

input.render(area, buf, &mut state);

State: TextInputState expone content: String, cursor: usize, y métodos de edición (insert_char, delete_before, delete_at, cursor_left/right/home/end).

Spin / ThemedSpin — Spinner atómico

Widget mínimo que renderiza un carácter animado. Al finalizar muestra ✓ (verde) o ✗ (rojo) según exit_code. ThemedSpin es un wrapper que añade los SpinVariant predefinidos.

State: SpinState con frame, finished, exit_code y un ScrollListState para salida asociada.


Constantes de estilo

Definidas en styles.rs y reexportadas desde la crate:

Constante Valor
BORDER_GRAY rgb(100,100,100)
OUTPUT_GRAY rgb(120,120,120)
FOOTER_GRAY rgb(140,140,140)
CHECK / CROSS /
HIGHLIGHT_SYMBOL >
POPUP_WIDTH PopupSize::Fixed(44)
DEFAULT_HIGHLIGHT letra blanca sobre fondo azul marino
DEFAULT_FRAMES frames braille para spinner braille
TEXT_PADDING padding horizontal 1

Licencia

MIT.