fix(ui): ComboBox y Flyout se portan a document.body con position:fixed
El panel desplegable de ComboBox se posicionaba con position:absolute dentro de su propio contenedor. Cualquier ancestro con overflow:hidden/auto (un Expander colapsable, el body de un DetailPopup, una tarjeta con scroll propio) lo recortaba, dejando la lista invisible o cortada a la mitad -reproducido en Configuracion > Apariencia, dentro del Expander-. Fix: igual tecnica que Flyout -createPortal a document.body, position:fixed calculado desde getBoundingClientRect() del trigger-, con cierre en click afuera y en scroll de cualquier ancestro (capture:true, el scroll no burbujea). De paso Flyout pasa de position:absolute a position:fixed por el mismo motivo (evita un bug latente de desalineacion si la pagina esta scrolleada). Regla documentada en project-md-templates/UI-UX-WINDOWS.md (Kit de componentes + do's/don'ts) para que no se repita en este ni otros proyectos. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+15
-2
@@ -111,9 +111,19 @@ openDialog({
|
||||
- **Campos** — `TextBox`, `NumberBox` (con spinner +/-), `ComboBox` propio (desplegable redondeado,
|
||||
con buscador si la lista tiene **≥10 ítems**; nunca el `<select>`/combo nativo del SO — no se puede
|
||||
redondear ni estilar), `Textarea`, `CheckBox`, `RadioButtons`, `ToggleSwitch` (interruptor), `Slider`.
|
||||
**Regla dura de implementación (bug real, recurrente):** el panel desplegable de `ComboBox` (y de
|
||||
cualquier control propio con un panel flotante — `DatePicker`, `Flyout`) **nunca** se posiciona con
|
||||
`position: absolute` dentro de su propio contenedor. Un ancestro con `overflow: hidden` o `overflow:
|
||||
auto` (un `Expander` colapsable, el body de un `DetailPopup`, una tarjeta con scroll propio) lo
|
||||
recorta y la lista queda invisible o cortada a la mitad. Portar el panel a `document.body` con
|
||||
`createPortal` y posicionarlo con `position: fixed` calculado desde `getBoundingClientRect()` del
|
||||
trigger (misma técnica que `Flyout`) — así queda fuera del árbol/clipping del contenedor. Cerrar el
|
||||
panel en scroll (`window.addEventListener('scroll', fn, true)`, con `capture:true` porque el scroll
|
||||
de un ancestro no burbujea) y en click afuera.
|
||||
- **DatePicker/TimePicker** — calendario propio en un **flyout** anclado al campo (navegación de mes,
|
||||
día de hoy marcado, selección resaltada con `accent`); igual criterio que `ComboBox`: no usar el
|
||||
selector nativo del SO por falta de control visual.
|
||||
selector nativo del SO por falta de control visual, y el mismo requisito de portal +
|
||||
`position: fixed` de arriba (no recortarse dentro de un contenedor con overflow).
|
||||
- **ListView/DataGrid** — tabla con encabezados **ordenables** (clic ordena asc/desc), columna de
|
||||
**selección múltiple** (checkbox), fila con **hover** y **estado seleccionado** (`accent/.14`), y
|
||||
**clic derecho** que abre el menú contextual de esa fila (ver §6). Alternativa por fila sin mouse
|
||||
@@ -304,7 +314,10 @@ Alt+Tab); si es una decisión puntual ligada al contexto actual, es un `ContentD
|
||||
debajo del listado en pantallas de gestión (usar `DetailPopup`). ❌ que un `DetailPopup` cambie de
|
||||
tamaño al moverse entre sus pestañas/secciones internas. ❌ montar `ContentDialog`/`DetailPopup` sin
|
||||
portal a `document.body` (queda atrapado en el stacking context de un ancestro y puede terminar
|
||||
tapado por otro overlay).
|
||||
tapado por otro overlay). ❌ panel desplegable de `ComboBox`/`DatePicker`/`Flyout` con
|
||||
`position: absolute` dentro de su propio contenedor (un `Expander`, el body de un `DetailPopup` o
|
||||
cualquier tarjeta con `overflow` lo recorta o lo oculta) — portar a `document.body` y usar
|
||||
`position: fixed` calculado desde el trigger.
|
||||
|
||||
> Para que una app "se sienta Windows moderna": misma barra de título, mismo panel de navegación,
|
||||
> mismos cuatro mecanismos de aviso (`ContentDialog`/`InfoBar`/`Toast`/`Flyout`) bien diferenciados,
|
||||
|
||||
Reference in New Issue
Block a user