Cierra P1 #1 del audit Codex: «Eidos no importa `\$active-uix`
directamente — consume el runtime via `ActiveEidos.require()` que
expone la surface bounded (langs / format / prefs / dom / uix)».
`ActiveEidos` ya existe (src/uix/eidos/active-eidos.svelte.ts) y la
mayoria de eidos components la usan (accordion, alert-dialog, banner,
box, button, calendar, card, ~50 archivos). Estos 15 quedaban como
strugglers/adiciones recientes que se saltaron el patron.
Patron canonico aplicado en cada archivo:
-import { getActiveUix } from '\$active-uix';
-const uix = getActiveUix();
-uix.langs.t(...)
+import { ActiveEidos } from '\$uix/eidos';
+const eidos = ActiveEidos.require();
+eidos.langs.t(...)
Archivos (15):
- badge/badge.svelte
- format-date/format-date.svelte
- format-number/format-number.svelte
- image/image-{error,fallback,_}.svelte (3)
- password-field/password-field-caps-lock-indicator.svelte
- picker-shell/picker-shell-{cancel,clear,close}.svelte (3)
- relative-time/relative-time.svelte
- s-text/s-text.svelte
- skeleton/skeleton.svelte
- spinner/spinner.svelte
- trans/trans.svelte
Sin nueva surface introducida — todas las usages (langs, format.dates,
format.numbers, format.currency) ya estaban expuestas en
`ActiveEidos`.
Verificacion:
- `grep getActiveUix src/uix/eidos/components/ --include='*.svelte'`:
cero matches. Quedan referencias en comments/READMEs/types.ts
(informativas, no imports).
- `npm run check`: 0 errors mantenido.
- HTTP 200 en /uix/components/{trans,format-date,format-number,relative-time,badge,skeleton,spinner,image}.
Esto es el fix correcto del audit (no la migracion-a-soma del commit
anterior que se hizo por mal entendimiento de la regla — revertida en
el commit precedente «Revert ... service components from Eidos to
Soma»).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
<Trans> es un service component — un wrapper greppable de
getActiveUix().langs.t / ts. Resuelve un idlangref o un path a
traves del catalogo activo de langs y renderiza el texto traducido.
Familia con <FormatDate>, <FormatNumber>, <RelativeTime>: todos
son wrappers tipados del runtime para que un audit i18n encuentre cada
sitio que toca el catalogo con grep "<Trans".
Superficie
<!-- 5 modos de resolucion --><Trans>#?common.save|Save</Trans><!-- children como idlangref --><Transvalue="#?common.save|Save"/><!-- value prop --><Transpath="common.save">Save</Trans><!-- path + children=fallback --><Transpath="common.greet"params={{name:'Juan'}}/><Transas="strong">#?ui.required|Required</Trans><Transpath="common.save"locale="en-US">Save</Trans>
Props clave
Prop
Tipo
Default
Notas
value
LangString
—
idlangref (#?path|fallback) o literal.
path
string
—
Dotted path al catalogo (ej. 'common.save').
params
Record<string, unknown>
—
Interpolacion para path.
locale
SupportedLocale
runtime
Override por instancia.
trim
boolean
true
Trim del texto capturado de children.
as
keyof HTMLElementTagNameMap
'span'
Tag HTML.
children
snippet
—
Fallback / source si no hay value / path.
Modos de resolucion
Modo
Forma
Source
1. Children-only
<Trans>#?common.save|Save</Trans>
DOM textContent parseado como idlangref.
2. Value prop
<Trans value="#?common.save|Save" />
value parseado.
3. Path + children fallback
<Trans path="common.save">Save</Trans>
t(path) con children como fallback si la key no existe.
4. Path + params
<Trans path="common.greet" params={{name}} />
t(path, params).
5. Pass-through
<Trans value="literal text" />
Texto literal sin resolver.
Decisiones
Reactivo al locale: el $derived re-corre cuando el locale activo
cambia. La lectura va a traves de uix.langs.t / ts que estan
acopladas al sistema reactivo de runes.
Captura de children: cuando ni value ni path estan
presentes, el componente captura textContent del nodo via
bind:this={captureNode} + $effect. La primera render emite el
children original (#?path|fallback sin resolver); en $effect
intercepta y resuelve.
Cast del path: langs.t() tipa su primer overload con
${string}.${string} (template literal estricto). Como el runtime
acepta paths dinamicos en runtime, se castea via
Parameters<typeof t>[0].
Fallback a children: cuando t(path) devuelve el path original
(signal de "key no encontrada"), el componente cae al capturedText
si existe.
No CSS recipe: marker [data-trans] solo para tooling.