Bug behind the user's "el botón se desplaza en el eje contrario al
orientation" report. The Button recipe sets
[data-button]:active { transform: translateY(1px); }
on press to simulate a physical button push. Carousel prev/next triggers
absolute-position via:
[data-carousel-prev-trigger] { transform: translateY(-50%); } (horiz)
[data-carousel][data-orientation='vertical']
[data-carousel-prev-trigger] { transform: translateX(-50%); } (vert)
CSS `transform` is a single property — Button's :active value
REPLACES the carousel's centering transform, so on press the trigger
jumped off its anchor: in horizontal it lost vertical centering, in
vertical it lost horizontal centering AND moved 1px down (wrong axis
relative to slide travel).
Override `:active` on the carousel triggers to compose both transforms
on the appropriate axis:
horizontal: translateY(calc(-50% + 1px))
vertical: translateX(calc(-50% + 1px))
Now press feedback shifts the trigger 1px along the centering axis
without breaking the absolute anchor.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
active-uix
parent
8cf2fe813f
commit
92c5e421c9
@ -0,0 +1,61 @@
|
|||||||
|
# Eidos Carousel
|
||||||
|
|
||||||
|
Carousel es el wrapper visual de Eidos sobre el carrusel headless de Soma. Soma
|
||||||
|
posee indice, drag, teclado, autoplay, ARIA y disabled state; Eidos anade
|
||||||
|
chrome, tamano, color, botones de flecha con `Button` y receta CSS.
|
||||||
|
|
||||||
|
## Baseline Air
|
||||||
|
|
||||||
|
En la rama `morfo-runtime` no existe un `src/uix/air/components/carousel` visual
|
||||||
|
separado. La baseline local anterior vive en
|
||||||
|
`src/uix/soma/components/carousel`: root region, viewport, item-group, items,
|
||||||
|
prev/next triggers e indicadores.
|
||||||
|
|
||||||
|
Eidos conserva esa anatomia, pero la presenta como componente compound
|
||||||
|
`<Carousel>` con hijos explicitos (`Viewport`, `ItemGroup`, `Item`,
|
||||||
|
`PrevTrigger`, `NextTrigger`, `IndicatorGroup`, `Indicator`) y anade props
|
||||||
|
visuales (`size`, `variant`, `color`, `block`, `verticalBlockSize`).
|
||||||
|
|
||||||
|
## Comparativa
|
||||||
|
|
||||||
|
| Capacidad | APG / WAI-ARIA | Ark UI | shadcn-svelte / Embla | UIX |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| Root con nombre accesible | Recomienda `region` + `aria-roledescription` | Root + partes | Root visual + Embla API | Soma/Morfo |
|
||||||
|
| Prev/Next como botones nativos | Recomendado | `PrevTrigger` / `NextTrigger` | `Previous` / `Next` | Soma triggers + Eidos Button |
|
||||||
|
| Indicadores | Botones/tabs de seleccion | `IndicatorGroup` / `Indicator` | Dots via composicion | Soma indicators |
|
||||||
|
| Drag/swipe | No prescribe motor | Incluido | Embla | Soma `Gesture.base()` |
|
||||||
|
| Autoplay + pausa | Debe ser controlable | `autoplay`, pause cases | Plugin Embla | Soma timer + stop/pause props |
|
||||||
|
| Visual styling | Fuera de scope | Headless/data attrs | Tailwind recipe | Eidos recipe tokens |
|
||||||
|
|
||||||
|
Fuentes:
|
||||||
|
|
||||||
|
- [WAI-ARIA APG Carousel](https://www.w3.org/WAI/ARIA/apg/patterns/carousel/)
|
||||||
|
- [Ark UI Carousel](https://ark-ui.com/docs/components/carousel)
|
||||||
|
- [shadcn-svelte Carousel](https://shadcn-svelte.com/docs/components/carousel)
|
||||||
|
- [Embla Carousel Svelte](https://www.embla-carousel.com/docs/get-started/svelte/)
|
||||||
|
|
||||||
|
## Decisiones
|
||||||
|
|
||||||
|
- Los triggers de Eidos renderizan `Button iconOnly` por defecto. El icono es
|
||||||
|
decorativo (`aria-hidden`) y no debe ser target de puntero; el click pertenece
|
||||||
|
al boton nativo que trae el handler de Soma.
|
||||||
|
- `PrevTrigger`, `NextTrigger` e `Indicator` llaman a la API publica
|
||||||
|
`scrollPrev`, `scrollNext` y `scrollTo`, para que `stopOnInteraction` trate
|
||||||
|
todos los clicks como interaccion real de usuario.
|
||||||
|
- `Indicator` hereda el archetype global `indicator`, que por defecto es
|
||||||
|
decorativo y usa `pointer-events: none`. Carousel lo sobreescribe a
|
||||||
|
`pointer-events: auto` porque sus indicadores son botones/tab stops reales.
|
||||||
|
- `slidesPerView`, `slidesToScroll`, `align` y `gap` viven en Soma porque
|
||||||
|
alteran geometria y bounds. Eidos solo consume el resultado visual mediante
|
||||||
|
`data-*` y estilos.
|
||||||
|
- `verticalBlockSize` es Eidos-only: el eje vertical necesita una altura
|
||||||
|
acotada para que el viewport pueda recortar, pero no cambia el contrato ARIA.
|
||||||
|
|
||||||
|
## Gaps
|
||||||
|
|
||||||
|
| Gap | Disposicion | Detalle |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Pause/play trigger publico dentro del componente | diferir | La API imperativa ya expone `play`, `pause` y `reset`; una parte visual requiere Morfo/Soma. |
|
||||||
|
| Labels traducidos para slide/indicator generados por indice | implementar en Soma | El README de Soma ya documenta que parte del texto se arma en JS. |
|
||||||
|
| Tests browser-level permanentes | implementar | El fallo de click sobre SVG se verifico manualmente con Playwright; conviene convertirlo en test visual si el harness lo permite. |
|
||||||
|
| Motion attrs por direccion | diferir | Seria un extra visual para animaciones internas de slide. |
|
||||||
Loading…
Reference in new issue