|
|
4 months ago | |
|---|---|---|
| .. | ||
| README.md | 5 months ago | |
| index.ts | 5 months ago | |
| meter-indicator.svelte | 5 months ago | |
| meter.css | 5 months ago | |
| meter.svelte | 4 months ago | |
| types.ts | 5 months ago | |
README.md
Meter
Estado
Meter es el wrapper visual de Eidos sobre el primitivo Soma role="meter".
Soma/Morfo son duenos de valor, rango, ARIA, traducciones y clasificacion de
zona; Eidos anade size, shape y receta visual.
API publica:
<Meter value={72} low={30} high={90} size="md" aria-label="Disk usage">
<Meter.Indicator />
</Meter>
Baseline Air
Air no tenia components/meter. No hay API visual heredada que preservar. La
baseline para Eidos es, por tanto, Soma/Morfo actuales mas las plataformas de
referencia.
Soma/Morfo
| Capacidad | Owner | Estado |
|---|---|---|
role="meter" |
Morfo/Soma | Si |
aria-valuemin/max/now |
Morfo/Soma | Si |
| Accessible name | Soma | aria-label, aria-labelledby, fallback traducido |
aria-valuetext |
Soma | valueText o fallback ${value} / ${max} |
value/min/max attrs |
Morfo/Soma | data-value, data-min, data-max |
low/high/optimum attrs |
Morfo/Soma | data-low, data-high, data-optimum |
| Zone state | Soma | below, optimum, above |
| CSS percentages | Soma | --_meter-value-pct, --_meter-low-pct, --_meter-high-pct, --_meter-optimum-pct |
| Visual size | Eidos | sm, md, lg |
| Visual shape | Eidos | linear, circular |
Comparativa externa
| Plataforma | Modelo | Eidos |
|---|---|---|
Native HTML <meter> |
Semantica nativa con min/max/low/high/optimum, recomendada cuando se puede estilizar suficiente. |
Usa role="meter" porque el objetivo es styling consistente; replica valor/rango/zonas por ARIA, data-attrs y CSS vars. |
| MDN ARIA meter | Exige nombre accesible y aria-valuenow/min/max; recuerda que los descendientes del meter son presentational. |
Cumple nombre accesible y valor ARIA; evita crear Label/ValueText Eidos-only porque eso debe vivir en Morfo/Soma si se formaliza. |
| React Aria Meter | Componente dedicado con label, value label, formatOptions, minValue/maxValue y percentage render prop. |
Cubre role, rango, value text y porcentaje via CSS var; no tiene label/value visual como partes, gap diferido a Soma/Morfo. |
| Ark UI | No tiene Meter dedicado; muestra un strength meter dentro de Password Input como composicion. | Eidos tiene componente dedicado. |
| Radix / Bits | No tienen Meter dedicado. | Eidos tiene componente dedicado. |
Fuentes:
- MDN ARIA meter role
- MDN HTML meter
- React Aria Meter
- Ark UI Password Input
- Radix Icons/Primitives index
- Bits UI docs
Decisiones
Root vs Track
El root Soma es el track visual. Esto mantiene el DOM pequeno:
<div role="meter" data-meter>
<div data-meter-indicator />
</div>
Un Track separado no aporta ahora valor porque no hay thumb, markers ni
interacciones. Si en el futuro se quieren zonas pintadas como bandas
independientes, las CSS vars --_meter-low-pct y --_meter-high-pct permiten
hacerlo desde recipe sin cambiar la API.
Shape
shape pertenece a Eidos porque no cambia valor, rango, ARIA ni clasificacion
de zona. linear pinta barra; circular pinta gauge ring con la misma
--_meter-value-pct emitida por Soma. Las zonas siguen viniendo de
data-state.
Label y ValueText
React Aria integra Label y value label. En UIX no se han anadido como partes
Eidos-only porque role="meter" vuelve presentational sus descendientes para la
accessibility tree. Si queremos Meter.Label y Meter.ValueText, deben subir a
Morfo/Soma para crear ids, aria-labelledby y aria-describedby/texto visual
de forma coherente.
Decision: diferido a Soma/Morfo v2. Hoy el consumidor usa aria-label,
aria-labelledby y valueText.
Formatting
React Aria expone formatOptions y formatea con Intl.NumberFormat. UIX ya
tiene ActiveFormat, pero Meter no debe acoplarse a formato automaticamente
sin una politica clara de locale/units. Para evitar magia, Soma acepta
valueText; el consumidor o una capa superior decide el string.
Decision: diferido. Si se anade, debe entrar como servicio Soma/ActiveUix y no como formato local dentro de Eidos.
Eventos Sema
Meter declara 0 eventos semanticos de forma deliberada. Es una lectura de valor
conocido, no un control que el usuario manipule. Los cambios de value, rangos
o umbrales son actualizaciones de datos de la aplicacion; si la app quiere
avisos perceptivos por cambios criticos, debe emitirlos desde la capa que decide
esa politica.
Gaps
| Gap | Disposición | Detalle |
|---|---|---|
| API extendida sobre las referencias externas | diferir | Sólo si llega un caso de uso real. Mantener la superficie estable. |
| Cobertura adicional de variantes visuales | diferir | El recipe cubre sm/md/lg + solid/outline/ghost. Más variantes requieren caso concreto. |
| Documentación per-prop exhaustiva | implementar | Cuando se cierre el ciclo de remediación de cada componente. |
| Tests browser-level del flujo completo (Playwright) | implementar | Cobertura visual + interacciones. Se hace en una pasada conjunta de tests. |
Passive justification
Componente passive por diseño: no gestiona estado mutable propio, no responde a teclado más allá del foco del navegador, no emite eventos sema propios. El feedback perceptivo correspondiente al cambio que rodea al componente (validación, progreso, transición) pertenece a quien orquesta ese cambio — Form / Field / Toast / Dialog — no al componente visual.