You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/eidos/components/css-field
dev 3c059ff087
refactor(eidos): share number-field + css-field visual via spin-field
4 months ago
..
README.md refactor(eidos): share number-field + css-field visual via spin-field 4 months ago
css-field-decrement-trigger.svelte feat(uix): add CssField — validated CSS-value spinbutton + sium CSS helpers 4 months ago
css-field-increment-trigger.svelte feat(uix): add CssField — validated CSS-value spinbutton + sium CSS helpers 4 months ago
css-field-input.svelte feat(uix): add CssField — validated CSS-value spinbutton + sium CSS helpers 4 months ago
css-field-scrubber.svelte feat(uix): add CssField — validated CSS-value spinbutton + sium CSS helpers 4 months ago
css-field.css refactor(eidos): share number-field + css-field visual via spin-field 4 months ago
css-field.svelte feat(eidos): themeable stepper glyphs + css-field compact steppers 4 months ago
index.ts feat(eidos): themeable stepper glyphs + css-field compact steppers 4 months ago
types.ts feat(eidos): themeable stepper glyphs + css-field compact steppers 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-field recipe key (--spin-field-*) in src/uix/eidos/lib/recipes/base.ts.
  • Rules live in eidos/components/spin-field/spin-field.css (loaded via the foundation @import in index.css), selecting [data-spin-field*].
  • The css-field morfo declares structural identity (data-spin-field* on its parts), so those rules style it; css-field.css is 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: size xs..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.

Powered by TurnKey Linux.