4.9 KiB
RFC — Eje scaling (zoom global), separado de la densidad
Estado: ✅ IMPLEMENTADO. (diseño 2026-06-01 · implementado 2026-06-02) Surge de P1-2: la tipografía-por-densidad (
content-scale) estaba mal planteada. Densidad y zoom son cosas distintas; este RFC introduce el zoom como su propio eje.Código:
lib/config-types.ts(SCALING_KEYS/ScalingKey/DEFAULT_SCALING),lib/primitives/static.ts(STATIC_SCALING),lib/render-css.ts(appendScalingDeclarations/appendScaledMetricDeclarations/renderScalingBlocks),active-eidos.svelte.ts(scaling/scalingSource/getScaling()/data-scaling). Doc consolidada en THEMING.md §23.--density-scaley--density-content-scalefueron eliminados en este sprint.
0. Motivación
scaling en Radix Themes (90/95/100/105/110%) es un zoom global que escala
espacio, tipografía, alturas y line-box con UN factor — accesibilidad/zoom, no
densidad. Eidos tenía un --density-content-scale (±4%) muerto que intentaba
escalar tipografía bajo el eje de densidad, lo cual confunde densidad con zoom:
- Densidad (
compact/comfortable/spacious): aprieta layout (espacio + altura de control), texto estable (legibilidad — Material/Carbon). Ya hecho. - Scaling (este RFC): zoom — escala las métricas px incluida la tipografía.
Los dos ejes son ortogonales y componen (puedes tener compact + 110%).
1. Decisiones
- Discreto, paridad Radix:
90 / 95 / 100 / 105 / 110(%). Default100. Se proyecta como[data-scaling='90'](bloques, cacheable) +--scaling. - Escala (px):
font-size,space,control-height,icon-size. - NO escala:
line-height→ es ratio unitless (1.45…); ya escala vía el font-size escalado. Multiplicarlo lo duplicaría (bug). Excluir.border-width(1px nítido),radius(independiente — como en Radix),shadow,z-index,opacity,motion. Excluir.
- Composición con densidad (multiplicativa) en las 2 métricas compartidas:
--space-N: calc(base × var(--density-space-scale) × var(--scaling)),--control-height-N: calc(base × var(--density-control-scale) × var(--scaling)). - Poda
--density-scale(maestro) +--density-content-scale: eran el intento a-medias de lo que este eje hace bien. Reconcilia §20.1 (densidad = texto estable; scaling = zoom incluye texto).
2. Diseño
Primitiva (lib/primitives/static.ts):
export const STATIC_SCALING = { '90': 0.9, '95': 0.95, '100': 1, '105': 1.05, '110': 1.1 }
Default activo: 100.
Tipos (config-types.ts): SCALING_KEYS = ['90','95','100','105','110'],
ScalingKey. La primitiva de densidad pierde scale + contentScale.
Emisión (render-css.ts):
:rootdeclara--scaling-90: 0.9 … --scaling-110: 1.1(constantes) y--scaling: var(--scaling-100)(activo).- Bloques
[data-scaling='90'] { --scaling: var(--scaling-90); }… (los ≠100). font-size+icon-sizepasan de verbatim acalc(value × var(--scaling)).space+control-heightañaden× var(--scaling)alcalcque ya tienen.line-height,radius,border,shadow, etc.: sin cambios.
Runtime (active-eidos.svelte.ts): nueva scalingSource (get/onChange,
espejo de densitySource); apply() escribe data-scaling en el host (junto a
data-mode / data-density); dispose() lo limpia. EIDOS_SCALING_ATTR.
Contrato (contract.ts): emite --scaling + las constantes como knobs.
3. Conflictos (resueltos)
| Punto | Resolución |
|---|---|
| Densidad × scaling en space/control-height | Composición multiplicativa en el calc. Ortogonales en intención. |
| line-height (ratio) | NO escalar — escala vía font-size. |
| radius/border/shadow/z/opacity/motion | NO escalar (paridad Radix + corrección). |
--density-scale + content-scale muertos |
Podados — superados por este eje. |
size prop |
Ortogonal — size elige tier, scaling multiplica el valor del tier. Compone. |
| Zoom de navegador | Compone multiplicativamente (ambos px). Es app-level, distinto. |
| §20.1 (tipografía no escala con densidad) | Sigue cierto — densidad no la escala; scaling sí. Dos ejes. |
4. Plan de implementación
STATIC_SCALING+ quitarscale/contentScaledeSTATIC_DENSITY.- Tipos (
SCALING_KEYS/ScalingKey; ajustarDensityPrimitiveSet). render-css: emisión scaling + bloques +× var(--scaling)en las 4 familias; podar emisión de density scale/content-scale.ActiveEidos:scalingSource+data-scaling+ cleanup.contract: tokens scaling; quitar density scale/content-scale.- Regenerar
generated/base.css. - Tests: actualizar forma de
--space-4/--control-height(× scaling); test de font-size escalado; bloque[data-scaling]; test descalingSource. - Verificar (
check+vitest src/uix/eidos+ navegador) + doc en THEMING.md.