astra
alpha-0.1-background
alpha-0.1-dir-prefs
alpha-0.1-sec-dom
menubar-v4-safe
active-uix
morfo-runtime
morfo-driven-soma
semantuix
glm-5
main
sium-v1.0
${ noResults }
28 Commits (6a53c3dc991e53baac17045f72859b42de1e457c)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
b1b48fb3aa |
fix(sema,morfo,soma): una superficie no admite dos ocurrencias, y el nombre ya no miente
`data-event-*` es UNA RANURA por elemento. Tres auditorias independientes encontraron el mismo defecto y ninguna lo cerro: fable S1 (2026-07-01, con el README diciendo «findings executed»), sema S-17 (2026-08-05, midio el estampado del knob muriendo a los 24ms de un hold de 240) y blocks A-36/A-65 (reproducido en navegador, dos estampados a 1,1ms). Lo que faltaba no era diagnostico: nadie podia distinguir una redireccion legitima de una deriva, porque la opcion que redirigia se llamaba `fallbackTarget` y hacia lo contrario de lo que decia. EL NOMBRE PRIMERO. `fallbackTarget` -> `targetOverride` (202 apariciones, 64 ficheros, dirigido con `git ls-files`). Siempre GANO sobre el ref registrado; el nombre honesto es la precondicion para auditarlo. Las cronicas conservan el viejo por diseño. LA PROPIEDAD. `unstampEventAttrs` recibia el signal y lo DESCARTABA, asi que la ocurrencia que terminaba antes borraba a la que tenia la ranura. Ahora comprueba `data-event-id`. Con eso, `replace` deja de ser el comportamiento roto y pasa a ser el suelo correcto. A-36, SIN `regime`. Los cuatro overlays cedian el estampado del `open` al trigger por un workaround de la era `sequence: 'pre'`; con `post` el content ya esta montado. Retirado el override (float-panel migrado `pre`->`post`, ultimo fuera de la doctrina que sema.md escribe). Medido en /blocks/site-header/preview a 375px: contact-activate en el TRIGGER +18,7ms y open en el CONTENT +20,6ms, con press-squeeze y slide-from-right-full corriendo. Antes: los dos en el trigger, press-squeeze jamas. `regime` DEFINIDO — y son dos valores, no cuatro. `replace` (default) y `queue`, este solo para las 4 parejas irreducibles: los tres toggles (el provider ES el boton) y el knob. `collapse` retirado (su caso murio con la propiedad: medido, 0 huecos en 5 emisiones a 72ms) y `lock` retirado (significaria «un cierre que no se anuncia»), con sus 4 declaraciones muertas. El guard de `queue` PASO EN VERDE SIENDO INCORRECTO: con timers falsos no hay animaciones, asi que awaitExpression volvia al instante. El navegador midio el commit encolado llegando 1,6s tarde. `queue` espera el HOLD, no la expresion. Medir la envolvente no es medir la salida. `renderAttrs` — los attrs que no son partes. Vaciar ACTIVE_DEV_TRACK (palabras y chronos ya no estan excluidos) destapo 23 `data-palabras-*` que ningun morfo declaraba y que palabras.css SI estiliza: aterrizan en el arbol que el usuario escribio, asi que no pueden ser partes. Campo nuevo con la linea afilada —si el consumidor puede componerlo, es una PARTE— y 3 consumidores (palabras, waveform, aura). Declarado en types.ts Y en el esquema sium: la leccion de MorfoElement. Ademas: 5 selectores muertos en el predicado del focus-scope de palabras (barrido de todo el repo: aparecian solo ahi) · RTL-1 real en palabras-chrome (inset logico + translate fisico = doble volteo; rtl:check 1->0) · el union inline al `Direction` canonico, que destapo que el censo de direccion grepea el NOMBRE del tipo · deuda de chronos (scope, barrel, README). Y de la cola: S-36 (barrel 68->71 + guard), S-31 (vibrate(NaN)), S5 (la preferencia de reduced-motion del usuario ya gana a los channels del morfo), SO2 (el warn que el JSDoc prometia), SO4 (validar el target antes del prewrite). Todos los guards nuevos vistos fallar antes de arreglar nada. Base: check 74 (= base) · sema+morfo+contracts 454 verdes / 6 ajenos preexistentes · soma navegador 1258/1259 (el rojo es un timeout ajeno, reproducido con los cambios en stash) · docs:check 0/618 · rtl:check 0/177. Handoff: docs/process/CONTINUE-perceptual-surface.md Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
2870874cbb |
docs(opts): la auditoria exhaustiva del corpus — el canon deja de mentir
Barrido mecanico sobre los 673 .md del repo (1485 bloques de codigo en 319
docs): cada import contra la tabla de alias real, cada *Provider/*Opts contra
11481 simbolos del codigo, cada tabla de props de los 284 READMEs contra su
types.ts.
Causado por el eje de opts:
- active-architecture §8 (canon) daba OptsFromProps SIN el 4o parametro —el que
salva el `undefined`— y bindProps en forma v1; partOpts no aparecia pese a
ser el mecanismo de 288 wrappers. Tabla reescrita + las dos notas que la
tabla no puede llevar.
- architecture/soma.md tenia el UNICO bloque con bolsa manual que quedaba en
los 673, y sus DOS imports eran rutas fantasma ('../../reactive',
'../../props'). Ejemplo reescrito al canon.
- CONTINUE-direction afirmaba que switch no podia usar OptsFromProps y que
bindProps no acepta Active: falso por ambas mitades desde el eje. Marcado.
- CONTINUE-opts-canonicas se leia como plan VIVO con seis decisiones sin tomar
—una sesion futura habria rehecho 353 ficheros—: banner de cierre con lo que
cada decision acabo siendo.
- El invariante de catalogo sube al estrato arquitectura y gana filas de
aceptacion E-3.7 / E-3.8. drawer documenta que el snap SOBREVIVE al cierre;
knob y cropper precisan que su callback cubre reset y clamp.
Preexistentes que solo aparecen con el metodo exhaustivo:
- carousel documentaba `value`/`onValueChange`; son `index`/`onIndexChange` —y
el mismo README ya decia `index` doce lineas mas abajo.
- navigation-menu seguia con `skipDelayDuration`, renombrado a `groupSkipDelay`
en la pasada N6 (el propio types.ts registra el rename).
- textarea documentaba `submitShortcut` con **el default invertido**: el prop
es `submitOn` y por defecto es `false`, no 'mod+enter' —un consumidor
esperaba que Ctrl+Enter enviara de fabrica—, y `minLength` no existe.
- search-field ensenaba a envolver el callback en un debounce a mano (con el
alias `$lib`, retirado del proyecto) teniendo `debounceMs` propio: era
debounce sobre debounce.
- GESTURES nombraba SplitterTriggerProvider; la clase es
SplitterResizeTriggerProvider.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2 months ago |
|
|
d3c8fcfd37 |
docs(direction): los charts ya no estan en la cola — la linea llevaba rancia
§10.2 seguia diciendo que la familia chart "no tiene prop ni provider y resuelve
leyendo getComputedStyle(node).direction". Eso lo cerro 43a788083: los cinco que
necesitan direccion declaran dir?: Direction y resuelven por
createChartRtl(eidos, () => dir) -> activeEidosDir. Verificado por grep que no
queda un solo getComputedStyle(...).direction en la familia.
La linea me indujo a repetirlo. El registro historico de §9.20 se queda como
estaba — describe lo que era cierto entonces —; lo corregido es lo que apunta
hacia adelante.
Re-hace el cambio que
|
2 months ago |
|
|
7b0556a955 |
docs(direction): handoff del refactor — la direccion deja de ser una convencion
El usuario preguntó si lo entregado era lo mas logico y profesional. No lo es:
el contrato es correcto y el MECANISMO para cumplirlo es teclear la misma linea
en cada componente. 54 estampados a mano, 7 enlaces al padre a mano, 9 Content
que re-arrancan la cadena por su cuenta, y 20 de 55 componentes que lo
incumplian hasta `21055bd3c`. Una convencion que hay que repetir 54 veces y que
20 de 55 incumplian no es una convencion — es una abstraccion que falta.
`docs/process/CONTINUE-direction-runtime.md`, para abrir en sesion nueva. Lleva
LAS DOS COMPROBACIONES DE VIABILIDAD YA HECHAS, que es lo que separa un handoff
util de una idea:
- El runtime YA omite un atributo cuyo valor resuelve a `undefined`
(`runtime.svelte.ts:519-522`). Es exactamente la semantica del estampado
crudo. No hay que construir nada para eso.
- El runtime YA inyecta atributos sin declaracion en morfo — `id`, el marcador,
`data-archetype`, `reg.attachment` (`:538-551`), con el comentario que lo
justifica. Asi que el movimiento NO exige tocar 55 ficheros de morfo.
- La capa flotante tiene acceso al dueño: los sub-proveedores llevan
`this.provider`. Y el reparto de los 11 consumidores es el diagnostico —
8 pasan el `dir` DEL PROPIO Content (la fuga), 3 el de la raiz (lo correcto).
Dos movimientos, con el orden razonado (la propagacion primero: mas acotada,
verificable de un vistazo, y BORRA codigo, asi que el segundo llega a un arbol
mas limpio). Dos vehiculos posibles para el primero, sin decidir a proposito.
Lleva ademas la linea base exacta de verificacion y las trampas ya pagadas: el
crudo nunca resuelto, `dir` en un `<svg>` no hace nada, `OptsFromProps` quita el
`undefined`, clasificar por grep se equivoca (me paso con `avatar`), y una
migracion mecanica hereda los defectos que traduce.
⚠️ Anota lo que el refactor NO debe romper: los 4 que correctamente NO estampan
(popover, tooltip, link-preview, context-menu) y la excepcion firmada por el
usuario de `avatar`/`image`, que no aceptan `dir` a proposito.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2 months ago |
|
|
1cb61567e5 |
feat(direction): RTL-2 — el guard del doble volteo, la forma que se me colo dos veces
Cierra §10.1, la ultima deuda del eje. `dee2c9e3a` arreglo los dos defectos pero
dejo la FORMA sin guard, y es la que sobrevivio a la migracion §6.3 y a que yo
diera el eje por cerrado en §9.19.
LA FIRMA — dentro de un bloque cuyo prelude tiene `:dir()`, la misma familia
logica (`border`/`padding`/`margin`/`inset`-`inline`) declarada en LAS DOS caras,
EXACTAMENTE UNA con valor neutro (`0`, `auto`, `none`, `initial`, `unset`,
`revert`). Ese desequilibrio ES el espejo cancelado: la propiedad ya se habia
volteado cuando la regla matchea, asi que reubicarla la devuelve al punto de
partida y la deja en el borde opuesto al de sus hermanas.
Es mas estrecha que «bloque `:dir()` con puras logicas» a proposito. Una regla
que CAMBIA un valor bajo RTL sin reubicarlo es legitima —asimetrico por diseño
existe—, y las dos caras con valor son un autor describiendo dos bordes reales.
Lo que delata el defecto es el PAR, una cara apagada. Hay un test negativo por
cada uno de esos casos, que son los que evitan que la regla se vuelva ruido.
LAS TRES DECISIONES que el handoff dejaba abiertas:
- `:dir(ltr)` tambien entra. Igual de sospechosa, y no anade ruido.
- Marcador PROPIO, `rtl-mirror: <reason>`. Reutilizar `rtl-physical:` mentiria:
aqui no hay nada fisico, y un marcador que miente es peor que ninguno. Mismo
mecanismo (`exemptLines` toma ahora el patron por parametro), dos vocabularios.
Un test comprueba que el marcador de RTL-1 NO exime a RTL-2.
- Regla aparte, `lintRtlMirror()` con su propio `RtlMirrorFinding`. Los 14 tests
de RTL-1 quedan intactos y el tipo lleva los campos que importan
(`family`/`neutral`/`payload`) en vez de forzar los de RTL-1.
VERIFICACION, en este orden:
- `rtl-lint.test.ts` 27/27 (14 de RTL-1 intactos + 13 nuevos).
- RECALL con el runner COMPLETO contra el arbol pre-arreglo: restaure los dos
ficheros de `dee2c9e3a^` sobre el arbol, corri `rtl:check` y los devolvi con
`git checkout` en el mismo bloque. **2/2 cazados** (`feed.css:147`,
`tree-view.css:211`). Probar la funcion no basta: el runner es lo que corre.
- `rtl:check` sobre HEAD: 1 error, el de `palabras`, preexistente y excluido.
- `docs:check` 0/0 sobre 564 docs. `check` 77 = linea base.
Un defecto de presentacion salio al hacerlo: el `calc()` multilinea de tree-view
partia el mensaje por el primer salto. Los campos que RTL-2 emite colapsan el
whitespace; con test.
Actualizados los textos que el handoff avisaba que quedarian obsoletos: el
`enforcement:` y §4 del contrato, la fila RTL del build contract, la fila X-1.6
del checklist, y los docblocks de `rtl-lint.ts` y `rtl-check.ts` — que son
doctrina, no adorno.
⚠️ Sigue siendo cierto lo que NINGUNA de las dos reglas ve: leen texto CSS. Un
`transform` inline escrito por JS, un preset de motion compartido y la geometria
SVG siguen necesitando el ojo en RTL.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2 months ago |
|
|
7aee33acda |
docs(direction): §10, la cola para manana — RTL-2 ya viene especificada y medida
La unica deuda del eje es el guard del doble volteo, y es la forma que se me
escapo DOS veces (en la migracion §6.3 y en el cierre §9.19). El handoff no la
deja como idea: la deja lista para implementar.
LA FIRMA, mas estrecha que «bloque `:dir()` con puras logicas» —eso daria falsos
positivos sobre reglas legitimas que cambian un valor bajo RTL—: dentro de un
bloque con `:dir()`, la MISMA familia logica aparece como `-start` y como `-end`,
una con valor NEUTRO (`0`/`auto`/`none`) y la otra cargando el valor. Ese es el
gesto «apago un lado y lo repinto en el otro», que cancela un espejo en vez de
crearlo.
MEDIDA ANTES DE ESCRIBIRLA, que es lo que la hace accionable:
- contra `dee2c9e3a^` (antes del arreglo): 2/2 cazados
- contra HEAD: 0 hallazgos sobre 18 bloques `:dir()`
Nace verde y con recall demostrado sobre defectos REALES. Si al implementarla
sale distinto de 0, es un hallazgo nuevo, no un fallo de la regla.
Con las cuatro piezas a tocar (`rtl-lint.ts` y su docblock —que es doctrina—,
`scripts/rtl-check.ts`, y los casos de test, positivos Y negativos), tres
decisiones que NO dejo tomadas (`:dir(ltr)` tambien; escape hatch propio o
reutilizar `rtl-physical:`; regla aparte o ensanchar RTL-1), y el aviso de que
al aterrizar quedan DOS textos obsoletos el mismo dia — los escribi diciendo que
el guard no ve esta forma.
⚠️ NO copiar mi prototipo: usa una regex ingenua sin anidamiento ni comentarios.
`rtl-lint.ts` ya tiene `parseBlocks()`, que da exactamente lo que hace falta.
§10.2 lleva el resto por valor (los charts deberian aceptar `dir` — la
divergencia declarada en §7 del contrato; la tabla de props ausente de
number-field; la numeracion duplicada preexistente del checklist) y §10.3 el
estado del arbol.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2 months ago |
|
|
961c1bf8be |
docs(direction): los 55 componentes que aceptan `dir` ya lo documentan
De los que aceptan la prop, la mayoria no la mencionaba en su README, y los que
si tenian seis redacciones distintas para el mismo hecho: «from Soma», «prefs»,
«soma config», «soma», «Override Soma defaults» y —la peor— «Inherited from Soma
when omitted», que se lee como herencia del PADRE, que es justo lo que la cadena
no hace.
Cada uno dice ahora QUE cambia la direccion EN ESE componente, leido de su propio
codigo (el JSDoc de la prop, los usos de `resolvedDir` en el provider, las reglas
`:dir(` de su receta), no una frase de plantilla. Y cada uno enlaza el contrato
una vez, en la primera mencion.
DOS AFIRMACIONES FALSAS, cazadas por el verificador adversarial:
- `feed` decia que la receta «mueve el rail del hilo al otro lado». No lo movia:
lo CANCELABA. Ese era el defecto arreglado en `dee2c9e3a`; el README describe
ahora lo que el codigo hace.
- `waveform` daba `prefs` como default. Falso: waveform es el caso DELEGANTE,
no llama a `activeDir`, y sin prop no hay atributo ni lectura de prefs —
hereda. Su Slider compuesto es quien corre la cadena.
Y dos que estaban mal COLOCADAS: `calendar` listaba `dir` bajo `## ARIA` (no es
un atributo ARIA) y `accordion` bajo `## HTML Attributes` describiendolo como
«la prop cruda», cuando lo estampado es prop O prefs.
CORRECCION AL PRIMER BARRIDO, por la ley de autoria: escribio la cadena literal
`prop → prefs → 'ltr'` en 54 ficheros. Eso es la forma restate-instead-of-link
que `docs/authoring.md` §1 prohibe citando este mismo fallo («'7 families'
sobrevivio en tres docs semanas despues de que el canon pasara a 8»). Retirada:
la cadena se enuncia UNA vez, en el contrato; el README conserva su efecto.
Tres READMEs de eidos ensenaban todavia el selector prohibido —y los tres se
equivocaban sobre su PROPIO CSS, que ya usa `:dir(rtl)`—: waveform, nav-tree y
toolbar (este ademas invertia la precedencia: «prefs o prop»; gana la prop).
⚠️ `number-field` no tiene tabla de props que ampliar; su `dir` sigue en su
seccion `### Direction resolution`, ahora enlazando el contrato. Fabricar una
tabla de una fila diria «`dir` es su unica prop».
Handoff §9.20 con el cierre, el doble volteo y como se colo.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2 months ago |
|
|
76c807d3c7 |
docs(direction): 9.19, el alias y los cuatro de solo-CSS — el eje queda cerrado
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
bfb58b9c78 |
docs(direction): 9.18, la auditoria de la canonizacion
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
3c73af90a3 |
docs(direction): 9.16 grupo A canonizado, 9.17 el grupo B es decision de API
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
8cda5fd252 |
docs(direction): 9.15, censo de canonizacion — 38 canonicos, 11 fuera de la norma
El censo de 6.12 estaba incompleto: contaba los wrappers con default duro pero no los que resuelven en el provider (4) ni los que no exponen dir (7). Ninguno esta roto hoy — verificado que number-field y scroll-area estampan lo mismo — pero quedan dos decisiones: mover la cadena al wrapper, y si los 7 sin prop deben exponerla. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
7b306ae5d7 |
docs(direction): 9.13 decidida (teclado fisico) y 9.14, el resize del float-panel en RTL
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
013af67d7b |
docs(direction): 9.12 color-picker cerrado por las referencias, 9.13 float-panel sin precedente
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
ac2ca97444 |
docs(direction): 9.11 ejecutada — el lang del documento ya sigue al idioma
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
23d2e94783 |
docs(direction): el dir vacio era el shorthand {dir} de Svelte, y el diagnostico del html lang
9.10 cierra el dir=\\` que 6.5 dejo sin investigar: el shorthand emite una asignacion de PROPIEDAD ademas del atributo, y con undefined queda la cadena vacia. No estaba en el SSR — lo escribia el cliente al hidratar. 9.11 deja el html lang diagnosticado pero NO ejecutado: la causa es app.html con lang=en hardcodeado, el arreglo seria corto (la shell ya registra language en prefs) pero cambia el contrato ownsAttrs de la proyeccion, y hay un argumento en contra — en apps con i18n por routing el lang lo fija el servidor. Decision de arquitectura, pendiente de criterio. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
3bfe2c6527 |
docs(direction): 8.3 cerrada — coarse eran 6 media queries, no 2, y el swipe con raton real
Seccion 9.9. Dos cierres y un hallazgo del usuario: - `pointer: coarse`: el catalogo tiene SEIS media queries, no las dos que 8.3 daba por unicas. Las cuatro sin mirar (list-surface, chat-message, radio-group, rotate-align) no tienen ninguna geometria de eje inline — `--list-item-height`, `opacity`, `min-block-size` e `inset: 0` + `min-*` logicos. Las dos que si la tenian son justo las que 6.2 midio con hit-test. Cerrado por lectura, que aqui basta porque lo que se comprueba es una AUSENCIA. - El swipe del carousel con el raton REAL del navegador: las 4 combinaciones dan espejo exacto. Cierra lo que 6.8 no consiguio disparar por simulacion. MÉTODO: el raton real avanza 2 posiciones de golpe (momentum) y `left_click_drag` no deja fijar la velocidad — lo que se comprueba es el SIGNO, no la magnitud. Y verifica la direccion ANTES de cada gesto: mi primera pasada midio creyendo estar en LTR con el toggle en RTL, y el resultado parecia un defecto inexistente. - Las flechas del carousel en RTL (arreglo en el commit anterior). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
07515eedf5 |
fix(motion,demos): dos desviaciones propias, encontradas auditando la sesion
1. La regla `:dir()` de `3c3d8e1ac` nacia SIN ACOTAR, o sea matcheaba cada elemento del documento para declarar una custom property que solo lee el nodo animado. Acotada a `[data-animation-style]:dir(...)`: `:dir()` se resuelve contra ese nodo, asi que el caso del subarbol anidado sigue cubierto y el coste deja de ser global. Medido igual que antes — origin 65.05px en RTL / 0px en LTR, con el borde de anclaje clavado en 0. 2. `releasePosition()` en la demo del float-panel (`1857c7854`) soltaba la posicion SIEMPRE, tambien con `useAnchor` apagado: cambiar `side` en modo libre re-centraba un panel colocado a mano. Condicionado al ancla, que es lo unico con lo que la posicion fijada es excluyente. Medido: con ancla off el panel se queda en (24,24); con ancla on sigue re-sembrando (start x=234 · end x=61). Y el hueco de metodo que las destapo: habia tocado `render-css.ts` —el generador de CSS de TODO eidos— corriendo solo los tests del ambito. La pasada COMPLETA da 8 fallos en 4 ficheros, y verifique que ninguno es mio cruzando lo que señalan contra `git diff --name-only 40db0b981..HEAD`: audio-player (sonido), aura + menubar (eje agentico), orca (hook timeout), soma-attr-audit (pasa en solitario: flaky bajo carga). Queda anotado en 9.7 un cabo suelto AJENO: 6.7 retiro la entrada de `data-ready` de `component-visual-attrs.test.ts` al migrar tabs, pero `contracts.test.ts` sigue marcando `data-ready` en radio-group y tabs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
8ec1095545 |
docs(direction): las tres piezas de graficas, y el tercer punto ciego de RTL-1
Seccion 9.6: cierre de metrics / bar-segment / chart-legend, el defecto del preset `grow-x` con sus medidas, y el renombrado de `placement`. Lo que merece quedar escrito: los tres se dieron por sanos en 7.2 mirando el CSS, y el CSS ERA correcto en los tres. Lo que fallaba era la ANIMACION, que no vive en el recipe sino en un preset compartido. Revisar una grafica en RTL no es solo leer su recipe — hay que disparar su entrada y mirar de donde crece. Y el tercer punto ciego de RTL-1, tras el transform inline del 6.7: un `transform-origin` en un preset de TypeScript. El guard lee CSS estatico; los presets y lo que pinta el JS siguen necesitando el ojo. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
3812cd196e |
docs(direction): cierre de 8.1 y 8.2, y la leccion de por que una demo no deja ver
Seccion 9 nueva: el eje horizontal del scroll-area (9.1-9.4), los tres
agujeros de observabilidad (9.5) y los sueltos (9.6). 8.1 y 8.2 marcadas
CERRADAS con puntero.
La leccion que se repitio tres veces y merece quedar escrita: una demo es
inobservable por motivos DISTINTOS, y hay que averiguar cual antes de
declarar el bloqueo —
1. el control existe y basta usarlo — "scroll-area no tiene eje horizontal
(maxScroll: 0)" era cierto solo en el valor por defecto; el chip
scrollbars="both" daba 258. El bloqueo no existia y no hubo que
construir nada.
2. falta el control — el drawer solo listaba los cuatro fisicos.
3. el control existe pero otro estado lo anula — float-panel tenia
useAnchor, pero una posicion ligada ganaba siempre.
Recorre los controles y mira QUE GANA.
Queda anotado, señalado y no tocado: 2.4 sigue viva (parts[2] de la demo del
slider indexa SecondaryRange en vez de Thumb, ahora linea 430) y float-panel
no expone prop dir — lee soma.prefs.getDir() directo, que es la cadena
documentada con el eslabon de prop ausente.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2 months ago |
|
|
40db0b9816 |
docs(direction): cierre del barrido de graficas, la regla de RTL en SVG, y la cola para manana
LAS 11 GRAFICAS DEL CATALOGO, REVISADAS. Ninguna de las siete que quedaban
necesitaba cambios, y por razones distintas que conviene dejar escritas:
bar-list ya lo resuelve con CSS logico; sparkline y bubble-chart heredan el
frame de <Chart> arreglado en 55070c688; y gauge, pie-chart, polar-area y
smith-chart son RADIALES — sus posiciones son angulos, no tienen eje de lectura
y es correcto que no espejen.
LA REGLA, ahora en la fila "RTL · SVG" del contrato de construccion y
desarrollada en eidos/components/chart/README.md §Direction. Son DOS decisiones
y no son la misma:
1) ¿espeja la composicion? solo si hay EJE DE LECTURA. Se invierte el rango de
pixeles de la escala, o se refleja la x. Los valores de Y no se espejan
nunca — un grafico es una secuencia leida como lee el lector, no un espejo.
2) `text-anchor` es LOGICO: si la composicion espeja se deja tal cual (voltear
ademas lo cancela); si no espeja se fuerza el fisico.
TRAMPAS DE MEDICION que me engañaron durante toda la sesion, en §7.3: el bbox de
un path espejado es identico al del original —mi "fingerprint" declaro sparkline
sin espejar cuando si lo hacia—; un test de "se sale del SVG" no ve una invasion
hacia DENTRO; el hueco del eje Y hay que medirlo contra el TICK y no contra la
linea; verificar en LTR no revela NADA de un defecto de RTL; y la pagina
"heatmap" tiene dos modos tras un control, asi que capturar el primer svg solo
enseñaba uno.
HANDOFF. La cabecera apunta a la §8 nueva, que es la cola priorizada: scroll-area
(dos señales, sin medir, y le falta una demo con eje horizontal), los agujeros de
OBSERVABILIDAD que impiden verificar drawer y float-panel, las verificaciones
pendientes, y la deuda ajena por gravedad —encabezada por los 91 ficheros de test
que falsifican Soma.require()—. Y una §8.5 con lo que NO hay que rehacer, para
que nadie repita el trabajo medido.
check 74 = linea base exacta.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2 months ago |
|
|
714a1ddb59 |
fix(carousel): en RTL el rail se movia AL CONTRARIO del dedo durante el arrastre
El usuario vio a mano lo que mi simulacion de puntero no consiguio disparar en cinco intentos. El swipe estaba mal, y no donde yo habia mirado. La decision de finishDrag SI voltea (isRtlHorizontal ? -offset : offset) y por eso la daba por buena. El defecto estaba en el PINTADO durante el arrastre: translate = base + dragOffset // base = indice, dragOffset = dedo itemGroupTransform = translate * flip // el flip caia sobre LOS DOS El recorrido por indice es LOGICO —N->N+1 mueve el rail a la izquierda en LTR y a la derecha en RTL— y debe voltear. `dragOffset` es el desplazamiento FISICO del puntero y no debe. Al voltear ambos, en RTL el rail se movia en sentido contrario al dedo: arrastras a la derecha y el contenido huye a la izquierda. Separados: solo baseTranslate lleva el signo. A/B con git stash, midiendo el transform A MITAD del arrastre —que no exige superar el umbral de gesto, y por eso ahora si es medible—: sin el arreglo, con el dedo a +100px el rail da Δ-100 (huye); con el arreglo, Δ+100 (lo sigue). LTR intacto en los dos casos. NOTA DE METODO, anotada en el handoff: para un gesto con umbral de distancia y velocidad, no intentes completar el swipe con page.mouse; mide el estado INTERMEDIO con el puntero aun abajo. Es lo que me faltaba en §6.8. DESCARTADOS CON MEDIDA, no se tocan: scroll-area FUNCIONA. Confirmado por el usuario y medido: con el toggle en auto, ES->ltr y AR->rtl, y el elemento pasa a direction:rtl. Su resolvedDir sigue siendo codigo muerto y el uso de scrollLeft sin verificar en un eje horizontal real, pero el componente responde a la direccion. chart NO NECESITA ARREGLO y las referencias lo respaldan. Medido: chartDir, legendDir y el texto de los ejes pasan de ltr a rtl; el eje numerico no se voltea. Es el consenso: Chart.js implemento RTL SOLO para leyendas y tooltips y mantiene abierto el issue de ejes/etiquetas (#11937, PR #6460), y el patron documentado es eje numerico LTR con textos RTL. amCharts es de los pocos con RTL integral. Y el sintoma «la demo no reacciona al idioma», reportado tres veces (virtual-list, carousel, scroll-area): medido en las tres, con el toggle en AUTO las tres reaccionan. Si el toggle esta en ltr/rtl explicito el idioma no manda, porque el intent gana sobre la derivacion. No es defecto, pero despista de forma sistematica: parece un interruptor de dos posiciones y es un ciclo de tres donde solo uno cede el mando al idioma, y el estado solo se lee en el title. Cerrarlo seria trabajo de la shell, no del eje. Verificado: check 74 = linea base exacta. 4/4 en carousel. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
f420c74920 |
fix(rating-group,splitter): dos wrappers se quedaron fuera de 013ceac57, y el arrastre del splitter no volteaba
Verificados los tres componentes que "tenian codigo de direccion" pero nadie habia comprobado que acertara. Dos estaban rotos. RATING-GROUP, roto por DOS motivos encadenados. 1) calcFromPointer medía (clientX - rect.left) / rect.width, una fraccion desde el borde FISICO izquierdo. En RTL los items van de derecha a izquierda, asi que la mitad que EMPIEZA una estrella es la derecha: pinchar la primera mitad visual daba la estrella entera. Volteado con el mismo `1 - pos` que ya usa el slider. 2) Y aun asi seguia sin funcionar, porque su WRAPPER se quedo fuera de la normalizacion de 013ceac57: tenia `dir = 'ltr'` como default duro —que ademas incumple "el atributo nunca tiene defecto"— y readableActive(() => dir) en vez de activeDir(() => dir, soma). Nunca consultaba prefs, asi que resolvedDir valia 'ltr' pasara lo que pasara. NATURAL-TIME-PICKER tenia el mismo agujero (dir ?? 'ltr'). Son los DOS unicos que quedaron fuera; los otros 36 si usan activeDir. Medido tras arreglar ambos: en RTL la mitad derecha da 2.5 y la izquierda la entera — espejo correcto. SPLITTER: el arrastre estaba roto, el teclado no. resizePanels toma un delta LOGICO —positivo agranda el panel de ANTES del handle— y recibia el delta fisico del puntero sin voltear. En RTL arrastrar a la derecha agrandaba el panel que debia encoger, y el arrastre CONTRADECIA a las flechas, que si pasan por getDirectionalKeys. Tras el arreglo: LTR arrastre +118 / ArrowRight +6; RTL arrastre -118 / ArrowRight -6 — espejo exacto y los dos de acuerdo. NOTA DE METODO, anotada en el handoff: al ver `resolvedDir = opts.dir.current ?? 'ltr'` en unos 30 providers di por hecho que a todos les faltaba el eslabon de prefs. Es FALSO — la cadena vive en el WRAPPER (activeDir), y el provider recibe la prop ya resuelta. El slider, que tiene ese mismo resolvedDir, voltea perfectamente. Antes de "arreglar" 30 componentes, mirar el wrapper. SIN VERIFICAR: scroll-area. Su resolvedDir aparece UNA sola vez —la declaracion—, o sea es codigo muerto, y usa scrollLeft en cuatro sitios sin tratar que en RTL los navegadores lo devuelven NEGATIVO (isAtLeft seria siempre cierto, el ratio del thumb saldria negativo). No esta medido porque el scroll-area de la demo no tiene eje horizontal. Verificado: check 74 = linea base exacta. 20/20 en splitter + rating-group + natural-time-picker. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
b550c8cd4b |
fix(virtual-grid,virtual-list): en RTL el contenido desaparecia — el ancla de celda era fisica sobre un sizer logico
Reportado por el usuario: en la demo del virtual-grid, voltear la direccion deja
la rejilla EN BLANCO. Reproducido y medido en Chrome.
LTR : 108 celdas, 70 visibles, primera en x=381 (borde del viewport)
RTL : 108 celdas, 0 visibles, primera en x=-5101 (fuera de la pantalla)
No era scrollLeft —esta en 0 en ambos casos—, era el anclaje de la celda:
position:absolute con top:0, left:0 y translate3d(columnStart). Los dos terminos
son fisicos y coherentes ENTRE SI, pero el sizer interno es
`inline-size: 6000px`, o sea LOGICO: en RTL desborda hacia la izquierda y ocupa
[-5101, 899], asi que su borde fisico izquierdo es donde el contenido TERMINA.
`left: 0` mandaba las 108 celdas justo ahi.
Arreglado con ancla logica (inset-inline-start) y el signo en el offset, de modo
que el recorrido se queda en translate3d: un virtualizador recoloca miles de
celdas y conviene que siga en el compositor en vez de animar layout. Medido tras
el arreglo: 70 visibles en RTL, primera en x=779 = borde derecho del viewport
menos el ancho de celda, que es el inicio logico.
virtual-list tenia el MISMO patron (left:0 + translateX) y por tanto el mismo
defecto en modo horizontal. Mismo arreglo. El modo vertical no se ve afectado:
inset-inline-start:0 con width:100% es exactamente lo que left:0 era. Verificado:
12 items visibles en RTL, primero en x=755.
EL OTRO SINTOMA REPORTADO NO ES UN DEFECTO. «El cambio de idioma no le afecta»:
con el toggle en `auto`, elegir arabe voltea la lista correctamente —medido,
htmlDir y el direction computado del componente pasan a rtl—. Si el toggle esta
en ltr/rtl EXPLICITO el idioma no manda, porque el intent gana sobre la
derivacion; es lo ratificado en
|
2 months ago |
|
|
caf3cfd884 |
fix(float-panel): la semilla anclada usa la matematica de $ethereal en vez de una copia sin direccion
Verificados uno a uno los cinco componentes de la §2.2 del handoff, y despues barrido el punto ciego del guard. Ningun cambio de comportamiento salvo el de float-panel. LOS CINCO DE §2.2 ESTAN SANOS. slider: click al 25% del ancho FISICO da 75 en RTL, arrastrar a la derecha sube en LTR y baja en RTL, y ArrowRight igual. number-field y css-field: el mismo arrastre fisico sube en LTR y baja en RTL. dropdown-menu: el panel raiz se alinea al inline-start y el submenu abre a la derecha en LTR y a la izquierda en RTL. carousel: el track voltea (Next mueve -622px en LTR y +622px en RTL). Ninguno necesito arreglo. EL SWIPE DEL CAROUSEL NO ESTA MEDIDO. Cinco intentos de simulacion de puntero y no consegui disparar el gesto de forma reproducible ni en LTR: la capa tiene umbral de distancia y de velocidad. El signo esta bien por LECTURA (isRtlHorizontal ? -offset : offset). Son diez segundos con un raton de verdad. UN MOTOR CUBRE NUEVE COMPONENTES. soma/layers/floating lo consumen combobox, context-menu, dropdown-menu, link-preview, menubar, popover, select, sidebar y tooltip. Verificado a traves de popover (align=end: derecha en LTR, izquierda en RTL) y menubar (align=start, al reves). Los nueve quedan cubiertos. FLOAT-PANEL NO USA ESE MOTOR, Y HACE BIEN: useFloating mantiene el panel PEGADO a su ancla, y un float-panel se arrastra y redimensiona libremente. Pero su SEMILLA anclada si era redundante: computeInitialPosition() re-derivaba side + align contra el rect a mano, y esa copia resolvia align:'start' a r.left SIEMPRE — una alineacion LOGICA clavada a un borde FISICO, que nunca voltea. $ethereal ya exporta computeCoordsFromPlacement(rects, placement, rtl): pura, sincrona, sin ciclo de vida, y es la misma que usa el motor compartido. Migrada la semilla a ella. Se comparte la semilla, NO useFloating. anchored-seed.test.ts fija la migracion, porque la demo NO ancla ningun panel y el defecto no era observable ahi: en LTR el resultado es IDENTICO al algoritmo anterior en las 12 combinaciones side x align (cero regresion); en RTL con side vertical start y end se espejan; con side horizontal el align no cambia, que es el eje de bloque; y center sigue centrado en ambas. La demo, medida antes y despues, no se mueve. NO TOCADO, hace falta criterio: Home/End en el eje X llevan el panel a bounds.left / bounds.right. Para un panel que se arrastra libremente es defendible que sean extremos fisicos y no principio/final de lectura. Descartados como falsos positivos tras mirar el uso real: container (prop de margenes), text-focus, text-scramble y path-trace (miden donde esta algo para un efecto), drag-drop (sueltas donde ves), cropper (paneas una imagen que no se voltea) y gradient-builder (arrastras la parada donde la ves). Y drawer, que no aparecia en el primer cruce, esta BIEN y es el ejemplo a imitar: traduce start/end a left/right una sola vez en resolveDirection() y desde ahi todo es fisico y coherente — aunque su demo solo expone valores fisicos, asi que su mitad logica no es observable. Verificado: check 74 = linea base exacta. 12/12 en float-panel + 4/4 del test nuevo. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
76f18a5e87 |
refactor(tabs): el indicador pasa a MeasuredIndicator, y aparece un punto ciego del guard
Buscados los indicadores que comparten mecanismo con el de |
2 months ago |
|
|
dc5e956658 |
fix(direction): el indicador deslizante no se remedia al voltear la direccion
Verificar los tres arreglos que quedaron sin ver en
|
2 months ago |
|
|
ec533845d1 |
feat(direction): un guard para el eje logico-fisico, y el <main> que congelaba las 51 demos
Cierra la §2.1 del handoff. El guard nacio en rojo con 24 hallazgos y al arreglarlos aparecieron dos defectos mas grandes que el que buscaba. 1) EL GUARD RTL-1. Nada cruzaba un ancla LOGICA con un desplazamiento FISICO en la misma regla CSS: eidos-lint clasifica SELECTORES, no declaraciones, y la fila RTL del contrato de construccion decia "rule (LIVE)" — revision humana. Por eso el defecto del slider llego a produccion y lo cazo el ojo del usuario. Ahora `npm run rtl:check`, con la logica en src/uix/eidos/rtl-lint.ts (14 tests) para que sea testeable, calcando el par lint.ts / scripts/eidos-lint.ts. El test ancla el caso historico: slider.css ANTES de |
2 months ago |
|
|
86b6381388 |
docs(process): handoff del eje de direccion
Que esta cerrado (3 commits), que queda por orden de valor, y las trampas de metodo que costaron horas. Lo primero de la cola NO es codigo de componente: es el guard que no existe. Nada cruza `transform: translate*` con `inset-inline*` — hay 39 transforms en el CSS de eidos y ningun script los mira, porque eidos-lint solo clasifica selectores y el guard de la fila RTL del contrato es literalmente revision humana. Por eso el bug llego a produccion y lo cazo el ojo del usuario. Incluye la investigacion de las cinco librerias de referencia ya hecha (25 agentes, 5 hallazgos tumbados por refutacion) para que nadie la repita, y los dos datos que mas costaron: `unicode-bidi: isolate` NO arregla el interrogante desplazado, y `dir="ltr"` si — porque la hoja de agente del WHATWG le da isolate de propina. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |