Zetta v1.6

Components · Forms & selection

Slider

Custom-styled range slider with a visible fill bar and prominent thumb. Distinct from the native Range component. Extracted from zetta-form-v1_3.md (removed in v1.5) as a standalone file in v1.4.

Preview

Build with the skill

No package to install — hand this to your AI to generate or migrate the component in your stack.

Prompt for your AI
Apply the Zetta "Slider" component to this project using the zetta-design-md skill.

WHEN TO USE
- Migrating or fixing existing code (the common case): audit the current implementation against the `slider` spec and CORRECT every deviation — replace off-spec values, don't only add new ones.
- New component: build it to the `slider` spec in this project's stack.

AUDIT & FIX (when the component already exists)
Compare it to the skill's spec and fix, don't just append: hardcoded colors/hex, off-scale radius, wrong fonts, dark/navy fills, shadows used in place of borders (or missing borders), brand lime used as a CTA or interaction (must be primary indigo), and any missing or wrong hover / focus / active / disabled / invalid state or missing 2px focus ring. Replace each with the correct Zetta token.

ALWAYS
- Pull the authoritative spec and tokens from the skill — never guess or hardcode values.
- Use this project's own component conventions and framework idioms.
- Honor the Zetta guardrails (brand = identity only, primary = interaction, shadows for overlays) and verify in Light, Dark, and Accessibility.

Anatomy & rules

     ●━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━●
     ↑ thumb (20×20, canvas/primary) ↑
   ════════════                      ← slider-range (primary)
  ─────────────────────────────────  ← slider-track (surface-muted, 6px)
  ↑ paddingY: 19px expands hit area past 44px minimum
State Track Range fill Thumb
Default {colors.surface-muted} {colors.primary} Canvas fill, primary border, shadow
Hover Unchanged Unchanged Scale 1.1
Focus Unchanged Unchanged 2px solid {colors.border-focus} outline
Active (dragging) Unchanged Unchanged Scale 1.15, primary-bg fill
Disabled {colors.disabled-bg} {colors.disabled-text} Disabled border, not-allowed, 50% opacity

When to use

  • Adjusting a value within a known range where precision is less important than the relative position: volume, opacity, zoom, budget.
  • Settings panels where the user needs a visual feel for the value relative to the full range.

When not to use

  • Precise numeric entry — use Number Input.
  • Selecting from a small set of steps (2–5) — use Radio buttons.
  • Compact or inline context — use Range.

Do

  • Always show the current value — either as a thumb tooltip during drag, or as a read-only number input alongside the slider.
  • Set meaningful min, max, and step values with units in the label.
  • Allow the user to also type a precise value in an adjacent Number Input for power users.

Don't

  • Don't use slider without visible min/max labels or value display.
  • Don't use slider for values with more than 3–4 significant steps of difference — the thumb is too imprecise.
  • Label: noun + unit in parentheses. "Opacity (%)", "Budget (USD)", "Volume".
  • Min/max labels: show at the ends of the track — numeric value or descriptive ("Min" / "Max", "Quiet" / "Loud").
  • Thumb tooltip: show the current value during drag. Format matches the field unit: "75%", "$1,200", "0.5".
  • Error message: "Value must be between [min] and [max]." — only shown when value is set programmatically outside range.

Keyboard

Key Behavior
Tab Move focus to the slider thumb
Left / Down Arrow Decrease value by step
Right / Up Arrow Increase value by step
Page Down Decrease value by step × 10
Page Up Increase value by step × 10
Home Set to min
End Set to max

Accessibility

  • ARIA role: role="slider" on the thumb element.
  • aria-valuenow — current value (numeric, not formatted string).
  • aria-valuemin and aria-valuemax — define the range.
  • aria-valuetext — human-readable formatted value: "75 percent", "$1,200". Required when aria-valuenow alone is ambiguous.
  • aria-label or aria-labelledby on the thumb — must name the control, not just the value.
  • aria-disabled="true" when disabled.
  • Hit area: paddingY: 19px on the track expands the interactive area to meet the 44px minimum touch target.
  • Contrast: Primary-colored fill against {colors.surface-muted} track is visually clear but semantically backed by aria-valuenow — no contrast requirement applies to the fill indicator itself.

Spec

Values and token references resolved straight from the Zetta spec.

slider-track
backgroundColor
{colors.surface-muted}
height
6px
borderRadius
{rounded.full}
position
relative
display
flex
alignItems
center
cursor
pointer
paddingY
19px
slider-range
backgroundColor
{colors.primary}
height
100%
borderRadius
{rounded.full}
position
absolute
slider-thumb
backgroundColor
{colors.canvas}
borderColor
{colors.primary}
borderWidth
2px
width
20px
height
20px
borderRadius
{rounded.full}
shadow
{elevation.shadow.raised}
position
absolute
top
50%
transform
translateY(-50%)
cursor
pointer
transition
transform {motion.duration-fast}
slider-thumb-hover
transform
translateY(-50%) scale(1.1)
slider-thumb-focus
outline
2px solid {colors.border-focus}
outlineOffset
2px
slider-thumb-active
transform
translateY(-50%) scale(1.15)
backgroundColor
{colors.primary-bg}
slider-disabled
cursor
not-allowed
opacity
0.5
slider-track-disabled
backgroundColor
{colors.disabled-bg}
slider-range-disabled
backgroundColor
{colors.disabled-text}
slider-thumb-disabled
borderColor
{colors.disabled-text}
cursor
not-allowed