|
|
4 months ago | |
|---|---|---|
| .. | ||
| README.md | 5 months ago | |
| index.ts | 5 months ago | |
| number-field-decrement-trigger.svelte | 5 months ago | |
| number-field-increment-trigger.svelte | 5 months ago | |
| number-field-input.svelte | 5 months ago | |
| number-field-scrubber.svelte | 5 months ago | |
| number-field.css | 5 months ago | |
| number-field.svelte | 4 months ago | |
| types.ts | 5 months ago | |
README.md
NumberField
Estado
NumberField es el wrapper visual de Eidos sobre el spinbutton de Soma. Soma
posee parsing, formato, locale, direccion, teclado, wheel, scrubber, Field
integration, hidden input, estados de formulario y eventos perceptivos. Eidos
anade size, variant, color y la receta visual.
API publica:
<NumberField bind:value min={0} max={10} size="md" variant="surface" color="primary">
<NumberField.DecrementTrigger>-</NumberField.DecrementTrigger>
<NumberField.Input />
<NumberField.IncrementTrigger>+</NumberField.IncrementTrigger>
</NumberField>
Baseline old branch
La rama anterior no tenia air/components/number-field, pero si tenia
terra/number-field: root, label, input, increment y decrement. La migracion
actual mantiene el spinbutton/input/triggers y sube la etiqueta al componente
Field, porque UIX ya tiene una capa de campo comun para labels,
descripciones, errores y estados.
Soma/Morfo
| Capacidad | Owner | Estado |
|---|---|---|
role="spinbutton" |
Morfo/Soma | Si, en Input |
aria-valuenow/min/max/text |
Morfo/Soma | Si |
| Keyboard APG | Soma | ArrowUp/Down, Shift+Arrow, PageUp/Down, Home/End, Enter |
| Parsing locale-aware | Soma | soma.nums o Intl.NumberFormat fallback |
| Display/edit formatter split | Soma | Si |
| Percent edit scaling | Soma | Si, 0.75 edita como 75 |
| Mouse wheel | Soma | Opt-in via allowMouseWheel |
| Hold-to-repeat triggers | Soma | Si |
| Scrubber | Soma | Horizontal/vertical, sensitivity |
| Field integration | Soma | Hereda disabled/readonly/required/invalid y registra inputId |
| Form submission | Soma | Hidden input con raw value cuando name existe |
| Events | Morfo/Sema | commit-set, handle-pick, handle-scrub |
| Visual size | Eidos | sm, md, lg |
| Visual variant | Eidos | surface, outline, ghost |
| Intent color | Eidos | primary, secondary, neutral, affirm, fulfill, risk, threat, loss |
Comparativa externa
| Plataforma | Modelo | Eidos/UIX |
|---|---|---|
| WAI-ARIA APG Spinbutton | Text field focusable, optional increment/decrement buttons, arrows, Home/End y PageUp/PageDown. | Cumple el patron; triggers son tabindex=-1 para mantener foco en input. |
| React Aria NumberField | Label, Group, Input, Buttons, description/error, Intl formatOptions, wheel, commit behavior. |
Soma cubre formato, wheel, formulario y Field integration. commitBehavior='validate' queda como gap diferido. |
| Ark UI Number Input | Root, Control, Label, ValueText, Input, triggers, Scrubber, mouse wheel, clamp/overflow, invalid callbacks. | Soma cubre scrubber, wheel, clamp-on-blur y estados. Label/ValueText viven en Field, no como partes NumberField. |
| Base UI Number Field | Root, ScrubArea, ScrubAreaCursor, Group, Decrement, Input, Increment. | Soma cubre scrubber y triggers; no hay ScrubAreaCursor ni Group separado porque el root funciona como grupo visual. |
| Radix / Bits | Sin NumberField dedicado equivalente. | UIX tiene componente dedicado. |
Fuentes:
Decisiones
Label, description y error
React Aria y Ark integran Label/description/error dentro del componente.
UIX ya tiene Field, y NumberField se integra con el FieldProvider para
registrar el input y heredar estado. Duplicar NumberField.Label en Eidos
crearia dos formas de etiquetar el mismo control.
Decision: no se anaden partes Label, Description, ErrorText ni
ValueText en Eidos. Si se quiere un label visual, se usa Field.
Group / Control
Base UI y Ark separan Group/Control; Eidos usa el root como contenedor
visual de input + triggers. Esto reduce DOM y mantiene el recipe simple.
Decision: no se anade Group hasta que haya un caso real que necesite dos
contenedores visuales independientes.
ScrubAreaCursor
Base UI tiene un cursor visual para scrub. En UIX el scrubber ya expone
data-scrubbing y cursor CSS. Un cursor flotante requeriria comportamiento de
posicionamiento, no solo markup visual.
Decision: diferido a Soma/Morfo si aparece el consumer.
Sema
commit-set cubre teclado, triggers, wheel, blur/Enter y clear. handle-pick
se emite al iniciar scrubber, y handle-scrub durante el arrastre. El release
del scrubber vuelve a commit-set, de modo que el feedback continuo no
sustituye al commit final.
Commit behavior
React Aria distingue snap y validate. Soma tiene clampOnBlur: cuando es
true, clampa/redondea al blur; cuando es false, permite conservar el valor
redondeado sin clamp en blur. No existe todavia onValueInvalid.
Decision: suficiente para esta fase. onValueInvalid y validacion sin clamp se
documentan como gap Soma futuro.
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. |