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 }
8 Commits (0d7a97cb7ad839193ffeede68bc02135a766e978)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
5027c135fb |
feat(morfo)!: la ARISTA es ley — instrumento composition-aware, residuo a cero y el pase ARIA GATEA
El instrumento de la fila cero, en su forma magra firmada por ambos carriles: la identidad del compuesto YA viaja por la tubería única (cada parte compuesta estampa su attr identificador namespaced en el mismo elemento), así que morfo-check resuelve la arista desde los ATTRS CO-LOCALIZADOS — la cláusula del pase data («allow other components' part attrs») generalizada al ARIA que esas partes declaran. Cero superficie nueva de contrato. Índice de 919 attrs con guardia de colisión ruidosa (cero hoy, medido). Límites DECLARADOS en el header: ARIA de consumidor sigue flagged (search-field) · lo que no monta es invisible (clase RateButton) · dos-contratos-mismo-attr = check futuro nombrado. Disparador NOMBRADO para el marcador explícito: si el flip bidireccional del censo de fuentes destapa filas que lo estático no adjudica. Resultado medido: cosecha 258 → 16 → CERO (la clase de composición cayó al 100 % por construcción; dos pasadas byte-idénticas + confirmación con gate armado: 161/161, exit 0). El residuo, adjudicado leyendo: - card-group: la causa raíz era UN STRIP — la eidos amputaba data-collapsible-trigger/content «para que solo pinte Button/grid» (comentario literal). El attr identificador ES contrato, jamás un toggle de estilo: RESTAURADO, y el conflicto de pintura se resuelve con la arista EN CSS — collapsible guarda sus 4 bloques de trigger con :not([data-button]) (un Button del sistema trae su pintura — §15, el canal sigue al dueño) y card-group neutraliza el padding con el selector de DOS attrs [data-collapsible-content][data-card-group-content] (la arista como selector, especificidad 2). Verificado en vivo: pintura de Button intacta, padding 0, clip del colapso conservado, ambas aristas presentes. (El no-toggle con dispatch sintético es limitación de sonda — el Collapsible plano tampoco; perm-check con clicks reales lo ejercita.) - gradient-builder.angle-dial: forma de parte corregida — era un WRAPPER de layout declarando role slider + trío de un elemento que eidos renderiza como div contenedor del <Slider> compuesto (el Slider posee su semántica en SUS partes). - table demo: la celda FALSA deja de reclamar data-table-cell (attr de parte sin su parte = mentira al instrumento); su pintura prestada queda re-escrita demo-side. - Excepciones FIRMADAS ×2 con dueño de la cura: search-field.input ×3 (harness combobox escrito por LA DEMO) · palabras.status aria-live (la eidos escribe el div a mano por su propia doctrina 4.1.3 — fila del eje palabras). FLIP: el pase ARIA deja de ser advisory y GATEA (la ley P0: el gate se arma DESPUÉS del cero). La maquinaria advisory queda documentada como patrón de rollout de la casa para el próximo pase. morfo 264/264 · confirmación gateada 161/161 exit 0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
ffa45726fd |
feat(color)!: una palabra, un significado - primary/secondary son SIEMPRE jerarquia
La homonimia muere: `primary`/`secondary` significan JERARQUIA DE MARCA en el
catalogo ENTERO, tambien dentro de los seis primitivos de tinta (text, heading,
display, code, label, s-text). El paso de tinta del 82 % se llama `subtle` -
PROP y TOKEN, sin excepcion: el nombre es el contrato en el artefacto (la misma
ley que la FIRMA B' y la 12.9; se rechazo por escrito la via "solo el prop con
tabla de traduccion" - las excepciones legitimas son las FIRMADAS con razon,
no las inventadas al decidir para abaratar).
- Los seis CONTENT_INK, IDENTICOS: {subtle, muted, disabled, on-solid}; el
nivel-1 es el DEFAULT sin prop. `label` gana `on-solid` (cierra la
divergencia de familia registrada en
|
2 months ago |
|
|
9fc38b19a4 |
fix(demos): el contador de la pestaña Tokens se DERIVA del contrato — tres ya mentían
El panel de Tokens existe precisamente para no escribir a mano lo que el contrato ya sabe: pregunta a ActiveEidos.getRecipeTokens(). Pero el número junto a la etiqueta de la pestaña SÍ estaba escrito a mano, y derivó como deriva siempre una segunda fuente de verdad. Auditadas las 105 demos que montan el panel: 90 contadores correctos, 15 sin contador y TRES que mentían — carousel decía 30 y son 27, drag-drop 10 y son 9, link-preview 33 y son 35. Nadie edita un badge cuando cambia una receta. Nace web/routes/uix/lib/TokensTabCount.svelte, que hace la MISMA pregunta que el panel de debajo y filtra los forwards con guion bajo. 102 demos convertidas; las tres que faltan (scroll-area, slider, tabs) están en manos de otra sesión y van en una segunda pasada, para que el índice compartido no vea nunca dos escritores sobre un fichero. Verificado en navegador: carousel pasa de decir 30 a decir 27, con 27 filas en el panel y ninguna sin resolver; metrics, que no tenía contador, dice 72 y lista 72. npm run check COMPLETED con los 72 errores preexistentes de la rama y ninguno en los 102 ficheros. Dos sesiones de esta tanda discreparon sobre si poner el contador —una lo puso a mano, otra lo omitió por ser justo lo que el panel evita—. Tenían razón las dos a medias: el contador es útil y no debe escribirse. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
564133b485 |
feat(table): la rejilla se vuelve temable — 0 % → 86 %
Segundo del bloque F2-A. 46 knobs sin una sola entrada de contrato; ahora 45
claves públicas.
censo 0 % → 86 % · global 39 % → 40 %
computed 13.050 valores en 7 estados: **0 diffs**
**Una trampa esquivada de milagro**: `table` YA tenía bloque en `base.ts` — los
forwards de paleta THM-2. Insertar uno nuevo habría creado un segundo bloque
`table:` y el catálogo lo habría descartado EN SILENCIO (gana el último). Las
claves se fusionan en el existente; el guard de duplicadas lo confirma.
**Dos nombres corregidos, como decía el veredicto**: lo que el privado llamaba
`root-height-{k}` es la altura de la FILA (`row-height-{k}`), y el prefijo
`root-` desaparece del resto — el envoltorio ES el componente y
recipe-contract §1 no repite la parte en ese caso.
**Qué casa con el bundle y qué no**, medido eje a eje: la altura de fila sí
(1:1); el padding NO (la rejilla empaqueta más denso en xs y más suelto de md
en adelante — forzar el bundle cambiaría el default); y la tipografía casa
DESPLAZADA: de md en adelante la tabla tipa un paso por debajo
(`font-size-md` = `var(--size-sm-font-size)`), que es deliberado y ahora se lee
en el propio nombre de la coordenada en vez de esconderse en un primitivo.
**Dos hallazgos del arquetipo `item`, y ninguno es mío** — la fila lo lleva, y
ese velo de `archetypes.css` está a especificidad PLENA (0,5,0), a propósito:
1. **La prop `hoverable` no suprime nada.** Una fila se ilumina al pasar el
ratón aunque el atributo no esté — medido con hover real, y ocurría ANTES de
tocar esta receta. El arquetipo y la prop no se ponen de acuerdo sobre quién
decide: es decisión de morfo, se presenta, no se toca de oficio.
2. **`selected-row-fg` era un token que mentía.** La misma regla fija el
`color` de la fila seleccionada y gana a la receta (0,5,0 contra 0,3,0), así
que el token no podía mover nada nunca. Lo cazó el centinela; retirado con su
declaración muerta. La tinta de la fila seleccionada es del arquetipo.
Y una corrección de rumbo a mitad de camino: al pasar todo a `background-color`
el velo apareció en 3 sort-triggers (su velo sí va en `:where()`, 0,0,0). Eso
es el barrido sistemático del velo, que NO está firmado — así que en los nodos
velados se mantiene el atajo a propósito, con el porqué escrito en la línea.
Primero lo diagnostiqué como regresión mía; la medición lo corrigió.
Los 6 knobs que quedan: 3 privados de paleta (patrón THM-2, capa compartida) y
3 literales de layout/identidad (`inline-size: 100%` ×2, `opacity: 1`).
El test `horizontal-escape` afirmaba el nombre del privado; ahora afirma el
público, que es justo lo que este eje persigue.
audit PASS · eidos-lint 0 invalid · rtl 0 · docs 0 · check 0 en tocados ·
suite: sólo el rojo conocido `skin-media-player`
Demo con tab Tokens: 46 filas, 0 sin computar. README con «Talla y tema» y los
dos hallazgos del arquetipo.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2 months ago |
|
|
b906dd4077 |
fix(direction): el atributo `dir` se estampaba VACIO cuando nadie lo afirmaba
El contrato de `013ceac57` dice que `dir` se OMITE cuando nadie ha afirmado una
direccion. `6.5` habia visto `dir=""` en sidebar y tree-view sin averiguar de
donde salia. Es el shorthand `{dir}`: para `dir` Svelte emite una asignacion de
PROPIEDAD ademas del atributo, y con `undefined` el resultado es la cadena
vacia en vez de la omision. Atrapado con un trap sobre `setAttribute` + el
descriptor de la propiedad: dos escrituras, la segunda por propiedad.
No estaba en el SSR (`dir=""` no aparece ni una vez en el HTML servido) — lo
escribia el cliente al hidratar.
Un valor invalido HEREDA, asi que nada pintaba mal; pero contradice la letra
del contrato y hace que `[dir]` matchee.
Arreglado con spread condicional, que si omite:
{dir} -> {...dir ? { dir } : {}}
- `tree-view` (eidos): el wrapper LO NECESITA cuando el valor es concreto — el
recipe selecciona con `[data-tree-view-root]:dir(rtl)` y ese div es el
ANCESTRO del provider que estampa el attr. Con el valor ausente hereda, que
es lo correcto.
- 26 demos: el arnes estandar (`data-uix-stage-area` / `data-uix-canvas-inner`).
Verificado: en `auto` solo quedan `<html>` (la proyeccion de prefs) y el
provider con su valor resuelto — cero `dir=""`; en `rtl` los tres elementos lo
reciben concreto; al volver a `auto` desaparece limpiamente. Las 26 rutas
sirven 200 y ninguna trae `dir=""`.
METODO: mi primer regex tambien matcheaba dentro de `dir={dir}` y dejo
`dir={...}` — dos ficheros con parse error que `check` cazo (76 vs 74). Contar
ficheros modificados NO basta; hay que mirar el diff.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2 months ago |
|
|
5469e05df9 |
feat(direction): las demos dejan de clavar ltr, y la prosa inglesa se declara inglesa
Cierra el eje de direccion abierto en
|
2 months ago |
|
|
f8056f438b |
fix(demos): eliminate each_key_duplicate crash in 22 component demos
The event-trace inspector in each demo keyed its `{#each}` by a
`Date.now()` timestamp (`entry.at` / `h.at`). A single interaction can
stamp `data-event` on several elements within the same millisecond, so
two trace entries share the key and Svelte throws `each_key_duplicate`
(reported on dropdown-menu).
The trace is an ephemeral, 3-item, text-only log with no transitions or
stateful children, so positional reconciliation is correct: drop the
timestamp key (the each becomes unkeyed). The `fmtTime(...at)` display is
left intact.
Swept all 22 demos carrying the pattern (21 keyed by `entry.at` + announce
by `h.at`): dropdown-menu, context-menu, menubar, navigation-menu, listbox,
grid-list, table, tree-view, tree-grid, feed, command, carousel, drag-drop,
clipboard, announce, alert-dialog, button, color-field, link-preview,
range-calendar, time-field, time-range-field.
Verified: `as \w+ (\w+.at)` -> 0 occurrences site-wide; `npm run check`
0 errors; browser repro on dropdown-menu + table (burst of events, no
each_key_duplicate, console clean).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
4 months ago |
|
|
940e94bb64 |
Build TextArea component + fix locale propagation bug across soma providers
Major work in this session:
1. NumberField demo refactored to expose Intl.NumberFormatOptions live
- 9 canonical presets (currency/unit/percent/compact/plain)
- Locale/currency/unit lists derived from $libs/langs, $libs/currency,
$format/units (no more hardcoded arrays)
- Default locale from uix.format.numbers.getLocale()
2. Bug fix: locale prop ignored when soma.format service is active
- soma/NumberField: 5 bypass points via new `hasOwnLocale` getter
(decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue)
- soma/Calendar: dateOrder respects locale prop (matches DateField precedence)
- soma/RangeCalendar: same dateOrder fix
- When the consumer passes `locale` prop, soma.nums/dates is bypassed
and Intl is used directly with the prop locale
3. TextArea — new component, full 4-layer stack
- morfo: 3 parts (provider/input/count), 3 events
(commit-input/commit-submit/shift-count-overflow), APG textbox
- soma: TextAreaProvider with autosize (scrollHeight measurement),
submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp,
Field integration (OR-merge), counter overflow tracking
- eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize
- sema: commit-submit + shift-count-overflow perceptual cues
- demo: canonical 6-tab depth, all props exposed as live controls
- PrimitiveTextareaAttributes added to soma/types/html.ts
4. Also includes accumulated unreleased work from prior sessions:
- Eidos ports: announce, clipboard, drag-drop, feed, table,
tree-grid, tree-view, virtual-grid, virtual-list, words
- Their canonical demos under web/routes/uix/components/
- Semantic events defined for utility morfos
(announce/clipboard/virtual-list/virtual-grid)
- Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients)
- Sidebar reorganized with Data + Utilities groups
- Eidos words content layer and primitives
Reference library survey performed before TextArea API design (Mantine,
Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime).
Decision documented: no separate CurrencyField/UnitField — single
NumberField with formatOptions is the canon (matches all surveyed
headless libs except PrimeReact's mode enum, which still uses 1 component).
svelte-check: 0 errors in modified/created files.
See CONTINUE.md for full session notes and next steps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |