component

Input Range

A styled wrapper around <input type="range"> that shares the feedback, size, and background vocabulary of the rest of the form surface. The track fills proportionally with the current value so users see the selected amount at a glance.

Feedback

Apply semantic feedback colors to tint the filled track and thumb — useful for tying a slider to a validation state or a themed control group.

---
import InputRange from "../InputRange.astro";
import { stack } from "@pindoba/styled-system/patterns";
---

<div class={stack({ gap: "md", direction: "column" })}>
  <InputRange feedback="neutral" value={40} min={0} max={100} fullWidth />
  <InputRange feedback="primary" value={55} min={0} max={100} fullWidth />
  <InputRange feedback="success" value={70} min={0} max={100} fullWidth />
  <InputRange feedback="danger" value={25} min={0} max={100} fullWidth />
  <InputRange feedback="warning" value={85} min={0} max={100} fullWidth />
</div>

Size

Four sizes scale the track height and thumb diameter together so the control stays proportional inside tight toolbars or prominent settings panels.

---
import InputRange from "../InputRange.astro";
import { stack } from "@pindoba/styled-system/patterns";
---

<div class={stack({ gap: "md", direction: "column" })}>
  <InputRange size="xs" value={20} min={0} max={100} fullWidth />
  <InputRange size="sm" value={40} min={0} max={100} fullWidth />
  <InputRange size="md" value={60} min={0} max={100} fullWidth />
  <InputRange size="lg" value={80} min={0} max={100} fullWidth />
</div>

Prefix & Suffix

Use fieldPrefix and fieldSuffix to add labels or a live value readout alongside the track. The native <input> still owns the value — bind it to display the current number. Use labelPosition to place the labels inline with the track (default), or stacked on top or bottom.

Volume
35%
Brightness
72%
0
100
---
import InputRange from "../InputRange.astro";
import { stack } from "@pindoba/styled-system/patterns";
import { css } from "@pindoba/styled-system/css";
---

<div class={stack({ gap: "lg", direction: "column" })}>
  <InputRange value={35} min={0} max={100} fullWidth>
    <span slot="fieldPrefix" class={css({ whiteSpace: "nowrap" })}>
      Volume
    </span>
    <span
      slot="fieldSuffix"
      class={css({ minWidth: "3ch", textAlign: "right" })}
    >
      35%
    </span>
  </InputRange>

  <InputRange value={72} min={0} max={100} fullWidth labelPosition="top">
    <span slot="fieldPrefix" class={css({ whiteSpace: "nowrap" })}>
      Brightness
    </span>
    <span slot="fieldSuffix" class={css({ textAlign: "right" })}>72%</span>
  </InputRange>

  <InputRange value={60} min={0} max={100} fullWidth labelPosition="bottom">
    <span slot="fieldPrefix" class={css({ whiteSpace: "nowrap" })}> 0 </span>
    <span slot="fieldSuffix" class={css({ textAlign: "right" })}>100</span>
  </InputRange>
</div>

Custom Styling

The passThrough prop provides escape hatches for each slot: style accepts a Panda CSS SystemStyleObject and props forwards arbitrary HTML attributes to the corresponding element.

Wrapped in a surface via passThrough

Squared thumb via passThrough

Forwarded ARIA attributes

Opacity
50%
---
import InputRange from "../InputRange.astro";
import { stack } from "@pindoba/styled-system/patterns";
import { css } from "@pindoba/styled-system/css";
---

<div class={stack({ gap: "xl", direction: "column" })}>
  <div>
    <h3>Wrapped in a surface via passThrough</h3>
    <InputRange
      value={40}
      min={0}
      max={100}
      fullWidth
      passThrough={{
        root: {
          style: {
            background: "neutral.surface.step.1",
            borderRadius: "md",
            padding: "md",
          },
        },
      }}
    />
  </div>

  <div>
    <h3>Squared thumb via passThrough</h3>
    <InputRange
      value={65}
      min={0}
      max={100}
      fullWidth
      passThrough={{
        input: {
          style: {
            "&::-webkit-slider-thumb": { borderRadius: "xs" },
            "&::-moz-range-thumb": { borderRadius: "xs" },
          },
        },
      }}
    />
  </div>

  <div>
    <h3>Forwarded ARIA attributes</h3>
    <InputRange
      value={50}
      min={0}
      max={100}
      fullWidth
      labelPosition="top"
      passThrough={{
        input: {
          props: {
            "aria-label": "Opacity",
            "data-testid": "opacity-slider",
          },
        },
      }}
    >
      <span slot="fieldPrefix" class={css({ fontWeight: "medium" })}>
        Opacity
      </span>
      <span slot="fieldSuffix" class={css({ textAlign: "right" })}>50%</span>
    </InputRange>
  </div>
</div>

Props

props · 12 total
prop type default req description
feedback "neutral""primary""success""danger""warning" "primary" Semantic feedback color scheme. neutral: Default. primary: Primary color. success: Green. danger: Red. warning: Orange.
size "xs""sm""md""lg" "md" Size variant. Scales the track height and thumb diameter. xs: Extra small. sm: Small. md: Default. lg: Large.
background "surface.soft""surface.step.1""surface.step.2""surface.step.3""surface.deep""transparent" "transparent" Surface background token applied to the root wrapper.
border PanelBorder "none" Border style inherited from the panel token set.
labelPosition "inline""top""bottom" "inline" Where to place `fieldPrefix` and `fieldSuffix` relative to the track. inline: on the same row. top: stacked above. bottom: stacked below.
fullWidth boolean false Stretch the root to fill its container.
min numberstring 0 Minimum value of the range.
max numberstring 100 Maximum value of the range.
step numberstring 1 Increment between valid values. Use `any` for continuous ranges.
value numberstring undefined Current value of the slider. Bind in Svelte or set explicitly in Astro.
passThrough { root?: { style?: SystemStyleObject; props?: Record<string, unknown> }; input?: { style?: SystemStyleObject; props?: Record<string, unknown> }; prefix?: { style?: SystemStyleObject; props?: Record<string, unknown> }; suffix?: { style?: SystemStyleObject; props?: Record<string, unknown> } } undefined Custom styling and props for each slot of the input-range.
...rest HTMLAttributes<HTMLInputElement> - Standard HTML input attributes passed to the inner input element.