gioser

tawasuyu/llimphi

Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.

Rust 229TOML 101Markdown 82Shell 24052 Definiciones

⎇ main widgets/text-area/src/lib.rs Rust · 67 líneas · 2.5 KB Historia Quién tocó qué crudo

chore: refresco desde el monorepo — 27 crates nuevos (anim, lottie, svg, mesh, image, layer, test, wire-view, widgets rag-sidebar/router/lazy-list/rive-button) y sync de los 95 existentes 93253cc22 · Sergio ·

1//! `llimphi-widget-text-area` — input de texto **multilínea**.
2//!
3//! **El motor real vive en [`llimphi_widget_text_input`]** (módulo `area`): el
4//! mismo `EditorState` que el single-line, con hit-testing 2D (renglón + columna
5//! por glifos reales), caret y selección a través de líneas, undo/redo,
6//! copiar/pegar e IME. Este crate es una **fachada** que re-exporta esa
7//! implementación con los nombres del text-area — no hay estado paralelo.
8//!
9//! Reemplazó al viejo text-area de `String` plano (Enter→`\n`, Backspace, caret
10//! bloque al final del último renglón, sin posicionar, sin selección): era un
11//! sustituto de plástico del motor que ya existía. Ahora hay **una sola fuente
12//! de verdad**.
13//!
14//! ## Uso
15//!
16//! ```ignore
17//! use llimphi_widget_text_area::{new_state, text_area_view, TextAreaEvent, TextAreaPalette};
18//!
19//! // En el Model: un estado multilínea + un clipboard.
20//! let mut estado = new_state();               // = TextInputState::multiline()
21//! // En view():
22//! text_area_view(&estado, "Escribe…", focado, 6 /*renglones*/, &pal,
23//!     |ev| Msg::Area(ev));
24//! // En update(): estado.handle_area(ev, &mut clipboard);
25//! ```
26//!
27//! Demo ejecutable: `cargo run -p llimphi-widget-text-input --example area_demo`.
28
29#![forbid(unsafe_code)]
30
31pub use llimphi_widget_text_input::{
32    text_area_view, Clipboard, MemClipboard, NullClipboard, TextAreaEvent, AREA_LINE_H,
33};
34
35/// El estado del text-area **es** el del text-input en modo multilínea: mismo
36/// motor, sin wrapper. Crea siempre con [`new_state`] (o
37/// `TextInputState::multiline`) — el `Default`/`new` de `TextInputState` es
38/// single-line y **no** aceptaría saltos de línea.
39pub use llimphi_widget_text_input::TextInputState as TextAreaState;
40
41/// La paleta es la misma del text-input (mismos tokens del theme).
42pub use llimphi_widget_text_input::TextInputPalette as TextAreaPalette;
43
44/// Constructor correcto de un estado de text-area: `EditorState` **multilínea**
45/// (acepta `Enter` como salto de línea). Evita el footgun de `TextAreaState::new`
46/// (que hereda el single-line del text-input).
47pub fn new_state() -> TextAreaState {
48    TextAreaState::multiline()
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[test]
56    fn new_state_es_multilinea() {
57        assert!(new_state().is_multiline());
58    }
59
60    #[test]
61    fn acepta_saltos_de_linea() {
62        let mut s = new_state();
63        s.set_text("a\nb\nc");
64        assert_eq!(s.text(), "a\nb\nc");
65        assert_eq!(s.editor().line_count(), 3);
66    }
67}