tawasuyu

tawasuyu/llimphi

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

Rust 238TOML 102Markdown 83Shell 24178 Definitions

⎇ main widgets/select/LEEME.md Markdown · 53 lines · 2.7 KB History raw

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-select
2
3*Read this in English: [README.md](README.md).*
4
5Control *select* / dropdown moderno.
6
7Modelado como un **gradiente de complejidad**: la misma pieza sirve
8desde el select más tonto hasta uno con carga asíncrona y badges, sin
9cambiar de widget — sólo se van encendiendo capas.
10```text
11  ┌──────────────────────────────┐
12  │ ◷  Pendiente            ●  ▾ │   ← disparador (cerrado)
13  └──────────────────────────────┘
14       │ click → view_overlay
15       ▼
16  ┃ ⌕ Buscar…                     ← caja de búsqueda (capa 2)
17  ┃ ✓ ◷  Pendiente        12      ← ítem rico: check · icono · label · badge (capa 3)
18  ┃   ◔  En curso          3
19  ┃   ◉  Hecho             ·       ← badge dot
20  ┃ ─────────────────────
21  ┃ ⟳  Cargando…                  ← estado async (capa 4): Loading / Error+reintento / vacío
22```
23## Las cuatro capas
24
251. **Select simple.** `SelectItem::new` + `select_trigger_view` (el
26   botón cerrado que muestra lo elegido) + `select_menu_view` con
27   `SelectPhase::Ready` montado en `App::view_overlay`. `on_pick(idx)`
28   devuelve el índice **original** del ítem elegido; la app lo guarda y
29   cierra el menú. Eso es todo.
302. **Buscable (combobox).** Pon `searchable: true`. La caja de arriba
31   pinta `query`; el tecleo lo rutea la app por `on_key` a un
32   `TextInputState` y re-filtra con `filter`. `step_active` mueve el
33   resaltado con ↑/↓ saltando deshabilitados; `resolve` traduce la
34   posición resaltada al índice original para Enter.
353. **Ítems ricos + badges.** Cada `SelectItem` lleva `icon`, `sublabel`
36   y un `SelectBadge` (conteo `12`, chip de texto `beta`, o dot de
37   estado) — reusa `llimphi-widget-badge`. La selección múltiple sale
38   sola: pasa varios índices en `selected` y el menú pinta el check ✓ en
39   cada uno (la semántica toggle/cerrar la decide la app).
404. **Carga asíncrona.** El menú no exige tener los datos: `SelectPhase`
41   distingue `Loading` (fila "Cargando…"), `Error` (mensaje + acción
42   `on_retry`) y `Ready`. El patrón: la app abre el menú, lanza
43   `Handle::spawn`, pinta `Loading`, y al volver el worker cambia a
44   `Ready`. Una *generación* (`u64`) descarta respuestas viejas si el
45   usuario reabrió/retecleó — ver el ejemplo `select_demo`.
46
47El look es el de `context-menu`: panel redondeado con borde hairline,
48filas como píldoras con hover suave, indicador accent en la fila activa,
49scrim full-screen que dismissa al click-fuera.
50
51---
52
53Parte de **llimphi** — ver [llimphi](../../LEEME.md).

LEEME.md

llimphi-widget-select

Read this in English: README.md.

Control select / dropdown moderno.

Modelado como un gradiente de complejidad: la misma pieza sirve desde el select más tonto hasta uno con carga asíncrona y badges, sin cambiar de widget — sólo se van encendiendo capas.

  ┌──────────────────────────────┐
  │ ◷  Pendiente            ●  ▾ │   ← disparador (cerrado)
  └──────────────────────────────┘
       │ click → view_overlay
       ▼
  ┃ ⌕ Buscar…                     ← caja de búsqueda (capa 2)
  ┃ ✓ ◷  Pendiente        12      ← ítem rico: check · icono · label · badge (capa 3)
  ┃   ◔  En curso          3
  ┃   ◉  Hecho             ·       ← badge dot
  ┃ ─────────────────────
  ┃ ⟳  Cargando…                  ← estado async (capa 4): Loading / Error+reintento / vacío

Las cuatro capas

  1. Select simple. SelectItem::new + select_trigger_view (el botón cerrado que muestra lo elegido) + select_menu_view con SelectPhase::Ready montado en App::view_overlay. on_pick(idx) devuelve el índice original del ítem elegido; la app lo guarda y cierra el menú. Eso es todo.
  2. Buscable (combobox). Pon searchable: true. La caja de arriba pinta query; el tecleo lo rutea la app por on_key a un TextInputState y re-filtra con filter. step_active mueve el resaltado con ↑/↓ saltando deshabilitados; resolve traduce la posición resaltada al índice original para Enter.
  3. Ítems ricos + badges. Cada SelectItem lleva icon, sublabel y un SelectBadge (conteo 12, chip de texto beta, o dot de estado) — reusa llimphi-widget-badge. La selección múltiple sale sola: pasa varios índices en selected y el menú pinta el check ✓ en cada uno (la semántica toggle/cerrar la decide la app).
  4. Carga asíncrona. El menú no exige tener los datos: SelectPhase distingue Loading (fila "Cargando…"), Error (mensaje + acción on_retry) y Ready. El patrón: la app abre el menú, lanza Handle::spawn, pinta Loading, y al volver el worker cambia a Ready. Una generación (u64) descarta respuestas viejas si el usuario reabrió/retecleó — ver el ejemplo select_demo.

El look es el de context-menu: panel redondeado con borde hairline, filas como píldoras con hover suave, indicador accent en la fila activa, scrim full-screen que dismissa al click-fuera.


Parte de llimphi — ver llimphi.