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.
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>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>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.
---
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>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.
---
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>| 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. |