|
|
4 months ago | |
|---|---|---|
| .. | ||
| README.md | 4 months ago | |
| css-field-decrement-trigger.svelte | 4 months ago | |
| css-field-increment-trigger.svelte | 4 months ago | |
| css-field-input.svelte | 4 months ago | |
| css-field-scrubber.svelte | 4 months ago | |
| css-field.css | 4 months ago | |
| css-field.svelte | 4 months ago | |
| index.ts | 4 months ago | |
| types.ts | 4 months ago | |
README.md
CssField (eidos)
Visual wrapper over Soma's css-field spinbutton. Adds only chrome — size,
variant, color — and projects them as data-* for the recipe. Parsing,
validation, the unit whitelist, scrubbing, keyboard and Field integration are
owned by Soma.
<CssField bind:value allowedUnits={['px', 'rem', '%']} size="md" variant="surface" color="primary">
<CssField.DecrementTrigger>−</CssField.DecrementTrigger>
<CssField.Input />
<CssField.IncrementTrigger>+</CssField.IncrementTrigger>
</CssField>
Props (visual)
| Prop | Type | Default |
|---|---|---|
size |
ResponsiveProp<'xs' | 'sm' | 'md' | 'lg' | 'xl'> |
'md' |
variant |
'surface' | 'outline' | 'ghost' (ControlVariant) |
'surface' |
color |
ColorRole (8 roles) |
'primary' |
steppers |
'split' | 'stacked' |
'split' |
steppers — split keeps the decrement/increment at the two ends (the default);
stacked collapses them into one compact column on the inline-end side (increment
on top, decrement on the bottom), which flips to the inline-start under RTL. The
compact arrow height tracks size (each arrow fills half the field height).
All Soma Provider props pass through (value, allowedUnits, keywords, validate, min/max, step, …).
Recipe — shared spin-field visual
CssField has no visual of its own: it IS a spin-field. Visually it is identical to
NumberField (bordered field + input + increment/decrement triggers + scrubber,
split/stacked layouts, sizes/variants/colors, themeable glyphs); only the value model
differs (soma: CSS value vs number). So both reuse ONE source instead of cloning:
- Tokens live under the shared
spin-fieldrecipe key (--spin-field-*) insrc/uix/eidos/lib/recipes/base.ts. - Rules live in
eidos/components/spin-field/spin-field.css(loaded via the foundation@importinindex.css), selecting[data-spin-field*]. - The
css-fieldmorfo declares structural identity (data-spin-field*on its parts), so those rules style it;css-field.cssis a stub.
[data-invalid] tints the border with --color-risk-border; [data-focused] /
[data-scrubbing] raise the focus ring. A theme tints just CssField by scoping the token
to its data-attr: [data-css-field] { --spin-field-bg: … }. See THEMING §34.
Themeable stepper glyphs — a trigger with no children renders a default glyph
from a token via :empty::before (the glyph is decorative; the button is labeled by
its aria-label). Override per theme: --spin-field-control-increment-glyph /
-decrement-glyph for the split layout, …-glyph-stacked siblings for the compact
column. Passing children to a trigger overrides the token for that instance.
Baseline
No Air baseline — new component. Originally cloned number-field's recipe + CSS with token
renames; that clone drifted (a refinement to one didn't reach the other), so both were
unified into the shared spin-field visual (see Recipe above + THEMING §34). No clone
remains.
Comparativa externa
Ningún sistema de referencia trae un campo de valor CSS con whitelist de unidades; los análogos más cercanos son los spinbuttons numéricos. La superficie visual coincide con la familia de inputs (DateField / NumberField / ColorField): borde + botones de control + scrubber opcional, 5 tamaños × 3 variantes × 8 colores.
| Plataforma | Modelo | Eidos/UIX |
|---|---|---|
| WAI-ARIA APG Spinbutton | Campo de texto enfocable + botones increment/decrement, flechas, Home/End, PageUp/Down. | Cumple el patrón; los triggers son tabindex=-1 para mantener el foco en el input. |
| React Aria NumberField | Label, Group, Input, Buttons, formatOptions Intl, wheel. Numérico puro. |
Soma cubre teclado/wheel/scrubber/Field; añade valor+unidad (allowedUnits) que React Aria no modela. |
| Ark UI Number Input | Root, Control, Input, triggers, Scrubber, clamp/overflow, invalid callbacks. Numérico puro. | Soma cubre scrubber + clamp + invalid; opera sobre dimensión CSS, no número. |
| Base UI Number Field | Root, ScrubArea, Group, Decrement, Input, Increment. Numérico puro. | Soma cubre scrubber + triggers; el valor es una cadena CSS con unidad. |
| Radix / Bits / shadcn | Sin campo numérico ni de valor CSS dedicado. | UIX tiene componente dedicado con validación ambivalente (funciones puras o schema sium). |
Fuentes:
Decisiones
- Subset:
sizexs..xl(text-input family),variant=ControlVariant,color= 8 roles. - Fixed control row height — triggers + scrubber inherit the resolved input height.
- No component-specific visual state beyond the Soma data-attrs (
data-invalid,data-focused,data-scrubbing).
Gaps
| Gap | Disposición | Detalle |
|---|---|---|
| Afijo de unidad separado (mostrar la unidad fuera del texto del input) | diferir | Hoy la unidad vive dentro del texto del input; un sufijo visual requiere markup + medición. Sólo si llega un caso real. |
calc(...) y valores de color |
descartar | Fuera del dominio de dimensiones; color ya lo cubre color-field. |
| Tests browser-level del flujo completo (Playwright) | implementar | Cobertura visual + interacciones, en la pasada conjunta de tests del catálogo. |