# Continue Fecha de corte: 2026-05-17. Rama: `active-uix`. ## Corte para continuar manana - Rama `active-uix` queda con la tanda Soma -> Eidos commitada por fases. - No se tocaron demos ni rutas; el trabajo fue en `src/uix/eidos/components`, `src/uix/eidos/lib/recipes/base.ts`, `src/uix/eidos/index.css`, CSS generado y documentacion. - Validacion de la ultima tanda: - `npx vitest run src/uix/eidos` -> 7 archivos, 84 tests OK. - `npm run check` -> 0 errores, 0 warnings. - `node --import tsx/esm scripts/eidos-lint-all.ts` -> 0 invalid, sin drift hotspots. - Regla nueva para continuar Eidos componente por componente: - La primera referencia es Air en la rama anterior (`glm-5:src/uix/air/components/{name}`) cuando exista. - Despues se compara con Soma/Morfo actuales y con referentes externos relevantes (Radix/Radix Themes, Ark UI, Bits UI, shadcn-svelte y React Aria si aplica). - Cada componente Eidos debe tener tabla en `components/{name}/README.md` con gaps y decisiones antes de tocar wrapper/recipe/tokens. - Objetivo: no dejar Eidos por debajo de Air ni de las plataformas de referencia en funcionalidades reales. - Primer componente auditado con el nuevo protocolo: - `Dialog`: comparado contra Air, Radix, Ark UI, Bits UI y shadcn-svelte. - Decision: no se crea `Dialog.Positioner`; `Content.position` cubre esa responsabilidad visual sobre la grid canonica 3x3. - Decision: se anaden overrides visuales `width`, `minWidth`, `maxWidth`, `height`, `minHeight`, `maxHeight` en `Dialog.Content`, serializados como variables privadas del recipe. Soma sigue siendo dueno de comportamiento. - Segundo componente auditado con el nuevo protocolo: - `Drawer`: comparado contra Air (`glm-5`), Soma/Morfo actuales, Vaul, shadcn-svelte y Ark UI Dialog como referencia de dialog/layer. - Decision: no se crea `Drawer.Positioner`; la geometria edge-anchored vive en `data-side` + `data-variant` y en la receta. - Decision: no se implementa `shouldScaleBackground` de Vaul en Drawer local; es un efecto global sobre el wrapper de app y requiere contrato de shell. - Decision: se anaden overrides visuales `width`, `minWidth`, `maxWidth`, `height`, `minHeight`, `maxHeight` en `Drawer.Content`, serializados como variables privadas del recipe. El size canonico `sm/md/lg/full` sigue como preset principal. - Tercer componente auditado con el nuevo protocolo: - `Popover`: Air no tenia equivalente en `glm-5`, por tanto la referencia local pasa a ser Soma/Morfo y la comparativa externa Radix, Ark UI, Bits UI y shadcn-svelte. - Decision: no se crea `Popover.Positioner`; la posicion pertenece a Soma Floating y Eidos solo consume `data-side`, `data-align` y variables CSS. - Decision: no se crean `Popover.Title`/`Description` hasta que exista caso real; Popover suele contener UI arbitraria y el etiquetado puede vivir en contenido consumidor. - Decision: se anaden `matchAnchorWidth`, `width`, `minWidth`, `maxWidth`, `height`, `minHeight`, `maxHeight` en `Popover.Content`, serializados como variables privadas. La receta usa transform-origin y available-height de Soma Floating. - Cuarto componente auditado con el nuevo protocolo: - `Tooltip`: Air no tenia equivalente en `glm-5`; referencia local Soma/Morfo, comparativa externa Radix, Ark UI, Bits UI y shadcn-svelte. - Decision: no se crea `Tooltip.Positioner` ni `Tooltip.ArrowTip`; Soma Floating y Soma Arrow son los duenos de esa geometria. - Decision: se anaden `matchAnchorWidth`, `width`, `minWidth`, `maxWidth`, `height`, `minHeight`, `maxHeight` en `Tooltip.Content`, serializados como variables privadas. La receta usa transform-origin y available-height de Soma Floating. - Decision: se alinea Soma con Radix/Bits: el tooltip cierra al activar/clicar el trigger por defecto. `disableCloseOnTriggerClick` queda como escape hatch en `Tooltip.Group` y `Tooltip`. - Componentes Eidos nuevos desde Soma: - `meter` - `progress` - `slider` - `pagination` - `rating-group` - `search-field` - `number-field` - `breadcrumb` - Siguiente decision antes de seguir migrando: - Continuar con componentes de riesgo bajo/medio (`field`, `toolbar`, `tag-group`) o parar a definir una tabla de migracion por componente para los grandes (`select`, `combobox`, `calendar`, `date-field`). - Para cada componente nuevo conviene escribir primero: partes Soma, props visuales Eidos, `data-*` que estampa el wrapper, tokens de recipe y attrs morfo-backed que consumira el CSS. Actualizacion Eidos component migration 2026-05-17: - Inicio de la migracion Soma -> Eidos siguiendo `soma/COMPONENT_GUIDE.md` y `eidos/components/README.md`. - Componentes migrados: - `Progress`: root visual `progress.svelte`, `Progress.Indicator`, `progress.css`, `types.ts` e `index.ts` con disciplined option C. - `Meter`: root visual `meter.svelte`, `Meter.Indicator`, `meter.css`, `types.ts` e `index.ts` con disciplined option C. - Decisiones aplicadas: - Eidos no crea comportamiento: ambos wrappers envuelven `Provider` e `Indicator` publicos de Soma. - La unica prop visual anadida es `size?: ResponsiveProp<'sm' | 'md' | 'lg'>`, resuelta con `ActiveEidos.resolve(...)` y proyectada como `data-size`. - `Progress` usa el `data-state` de Soma (`indeterminate`, `loading`, `loaded`) para cargar/terminar/indeterminado. - `Meter` usa el `data-state` de Soma (`below`, `optimum`, `above`) para zonas visuales; no se anade intent ni color en Eidos. - Los tokens base viven en `THEME_BASE_RECIPE_TOKENS` y se regenero `src/uix/eidos/generated/base.css`. - Guardias actualizadas: - `component-visual-attrs.test.ts` protege `data-size` en `Progress` y `Meter`. - `scripts/eidos-lint-all.ts` reconoce `data-floating-wrapper` como marcador publico actual y retira el sufijo legacy `flat`. - `components/README.md` refleja `meter` y `progress` como migrados. - Validado: - `npx vitest run src/uix/eidos` -> 7 archivos, 84 tests OK. - `npm run check` -> 0 errores, 0 warnings. - `node --import tsx/esm scripts/eidos-lint-all.ts` -> 0 invalid, sin drift hotspots. - Segunda tanda del mismo bloque: - `Slider`: root visual `slider.svelte`, partes `Range`, `Thumb`, `Tick`, `slider.css`, `types.ts` e `index.ts` con disciplined option C. - La receta usa las posiciones inline calculadas por Soma y solo define track, range, thumb, ticks, foco, disabled y size visual. - `component-visual-attrs.test.ts`, `components/README.md`, `THEME_BASE_RECIPE_TOKENS`, `index.css` y `generated/base.css` quedan actualizados. - Validado despues de `Slider`: - `npx vitest run src/uix/eidos` -> 7 archivos, 84 tests OK. - `npm run check` -> 0 errores, 0 warnings. - `node --import tsx/esm scripts/eidos-lint-all.ts` -> 0 invalid, sin drift hotspots. - Tercera tanda del mismo bloque: - `Pagination`: root visual `pagination.svelte`, partes `PrevTrigger`, `NextTrigger`, `Item`, `Ellipsis`, `pagination.css`, `types.ts` e `index.ts`. - El root conserva el snippet de Soma con `{ pages, totalPages }` y solo anade `size` visual resuelto por `ActiveEidos`. - La receta cubre controles, estado selected, disabled, ellipsis y focus. - Validado despues de `Pagination`: - `npx vitest run src/uix/eidos` -> 7 archivos, 84 tests OK. - `npm run check` -> 0 errores, 0 warnings. - `node --import tsx/esm scripts/eidos-lint-all.ts` -> 0 invalid, sin drift hotspots. - Cuarta tanda del mismo bloque: - `RatingGroup`: root visual `rating-group.svelte`, parte `Item`, `rating-group.css`, `types.ts` e `index.ts`. - No se inventa icono/star por defecto ni API nueva; el wrapper conserva los snippets de Soma (`items` en root y `state` en item) y la receta estiliza `active`, `partial`, `inactive`, foco, vertical/horizontal y disabled. - Validado despues de `RatingGroup`: - `npx vitest run src/uix/eidos` -> 7 archivos, 84 tests OK. - `npm run check` -> 0 errores, 0 warnings. - `node --import tsx/esm scripts/eidos-lint-all.ts` -> 0 invalid, sin drift hotspots. - Quinta tanda del mismo bloque: - `SearchField`: root visual `search-field.svelte`, partes `Input`, `ClearTrigger`, `search-field.css`, `types.ts` e `index.ts`. - El wrapper conserva el snippet de Soma (`value`, `isEmpty`, `isFocused`, `clear`) y solo anade `size`. - La receta cubre contenedor, input, clear trigger, focused, invalid, empty y disabled. - Validado despues de `SearchField`: - `npx vitest run src/uix/eidos` -> 7 archivos, 84 tests OK. - `npm run check` -> 0 errores, 0 warnings. - `node --import tsx/esm scripts/eidos-lint-all.ts` -> 0 invalid, sin drift hotspots. - Sexta tanda del mismo bloque: - `NumberField`: root visual `number-field.svelte`, partes `Input`, `IncrementTrigger`, `DecrementTrigger`, `Scrubber`, `number-field.css`, `types.ts` e `index.ts`. - El wrapper conserva formato/parseo/spinbutton/scrub de Soma y solo anade `size`. - La receta cubre contenedor, input, triggers, scrubber, focused, scrubbing, invalid y disabled. - Validado despues de `NumberField`: - `npx vitest run src/uix/eidos` -> 7 archivos, 84 tests OK. - `npm run check` -> 0 errores, 0 warnings. - `node --import tsx/esm scripts/eidos-lint-all.ts` -> 0 invalid, sin drift hotspots. - Septima tanda del mismo bloque: - `Breadcrumb`: root visual `breadcrumb.svelte`, partes `List`, `Item`, `Link`, `Separator`, `Ellipsis`, `breadcrumb.css`, `types.ts` e `index.ts`. - El wrapper conserva semantica, current item/link, ellipsis interactivo y ARIA de Soma; Eidos solo anade `size`. - La receta consume `data-current` y `data-interactive` declarados por Morfo y define tokens para gaps, tipografia, links, separador, ellipsis, foco y transiciones. - Validado despues de `Breadcrumb`: - `npx vitest run src/uix/eidos` -> 7 archivos, 84 tests OK. - `npm run check` -> 0 errores, 0 warnings. - `node --import tsx/esm scripts/eidos-lint-all.ts` -> 0 invalid, sin drift hotspots. - Siguiente bloque sugerido: - Migrar otro grupo de bajo riesgo desde Soma a Eidos: candidatos reales por morfo/soma existentes son `field`, `toolbar` o `tag-group`. - Antes de tocar componentes grandes (`select`, `combobox`, `calendar`, `date-field`) conviene fijar una tabla por componente: partes Soma, props visuales Eidos, recipe tokens y attrs esperados. Actualizacion Eidos components audit 2026-05-17: - Se acometieron los hallazgos autorizados sobre `src/uix/eidos/components` sin tocar demos ni rutas `web/routes/uix`: - `Tabs` instala su contexto visual de forma sincronica durante init, no en `$effect`; los hijos `Tabs.Content` ya no pueden inicializar sin contexto. - `Tabs.Indicator` deja de observarse a si mismo con `ResizeObserver`, para evitar loops de medida provocados por sus propias escrituras inline. - `Avatar.Image` ya no arranca oculto cuando hay `src`; la visibilidad queda derivada de `src` y de la ultima URL fallida. - `Accordion.Trigger` ya no contiene `