---
title: Slider
description: Range input for selecting numeric values.
icon: sliders
---

import { ComponentPreview } from "/snippets/component-preview.mdx";

Sliders let users select a numeric value from a range by dragging a handle. The default range is 0–100.

## Basic Usage

<ComponentPreview json={{"view":{"type":"Slider","min":0,"max":100,"value":50.0,"disabled":false}}}>
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import Slider

Slider(value=50)
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "type": "Slider",
    "min": 0,
    "max": 100,
    "value": 50.0,
    "disabled": false
  }
}
```
</CodeGroup>
</ComponentPreview>

## Displaying the Value

Give the slider a `name` to store its current value in state, then reference it with `{{ }}` interpolation. Drag the slider and the label updates instantly:

<ComponentPreview json={{"view":{"cssClass":"gap-2","type":"Column","children":[{"cssClass":"justify-between","type":"Row","children":[{"type":"Label","text":"Volume"},{"content":"{{ volume | number }}%","bold":true,"type":"Text"}]},{"type":"Slider","min":0,"max":100,"value":75.0,"name":"volume","disabled":false}]},"state":{"volume":75}}}>
<CodeGroup>
```python Python icon="python"
from prefab_ui.app import set_initial_state
from prefab_ui.components import (
    Column,
    Label,
    Row,
    Slider,
    Text,
)

set_initial_state(volume=75)

with Column(gap=2):
    with Row(css_class="justify-between"):
        Label("Volume")
        Text("{{ volume | number }}%", bold=True)
    Slider(value=75, name="volume")
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "cssClass": "gap-2",
    "type": "Column",
    "children": [
      {
        "cssClass": "justify-between",
        "type": "Row",
        "children": [
          {
            "type": "Label",
            "text": "Volume"
          },
          {
            "content": "{{ volume | number }}%",
            "bold": true,
            "type": "Text"
          }
        ]
      },
      {
        "type": "Slider",
        "min": 0,
        "max": 100,
        "value": 75.0,
        "name": "volume",
        "disabled": false
      }
    ]
  },
  "state": {
    "volume": 75
  }
}
```
</CodeGroup>
</ComponentPreview>

The `| number` pipe strips trailing decimals so the display stays clean. This pattern works with any component that supports interpolation.

## Range and Step

Use `min`, `max`, and `step` to constrain the slider. Here the range is 0–10 with 0.5 increments:

<ComponentPreview json={{"view":{"cssClass":"gap-2","type":"Column","children":[{"cssClass":"justify-between","type":"Row","children":[{"type":"Label","text":"Rating"},{"content":"{{ rating }}","bold":true,"type":"Text"}]},{"type":"Slider","min":0.0,"max":10.0,"value":5.0,"step":0.5,"name":"rating","disabled":false}]},"state":{"rating":5}}}>
<CodeGroup>
```python Python icon="python"
from prefab_ui.app import set_initial_state
from prefab_ui.components import (
    Column,
    Label,
    Row,
    Slider,
    Text,
)

set_initial_state(rating=5)

with Column(gap=2):
    with Row(css_class="justify-between"):
        Label("Rating")
        Text("{{ rating }}", bold=True)
    Slider(value=5, name="rating", min=0, max=10, step=0.5)
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "cssClass": "gap-2",
    "type": "Column",
    "children": [
      {
        "cssClass": "justify-between",
        "type": "Row",
        "children": [
          {
            "type": "Label",
            "text": "Rating"
          },
          {
            "content": "{{ rating }}",
            "bold": true,
            "type": "Text"
          }
        ]
      },
      {
        "type": "Slider",
        "min": 0.0,
        "max": 10.0,
        "value": 5.0,
        "step": 0.5,
        "name": "rating",
        "disabled": false
      }
    ]
  },
  "state": {
    "rating": 5
  }
}
```
</CodeGroup>
</ComponentPreview>

## With Actions

The `on_change` parameter runs actions when the slider value changes. `$event` is the current numeric value:

<ComponentPreview json={{"view":{"cssClass":"gap-4","type":"Column","children":[{"type":"Slider","min":0,"max":100,"value":50.0,"disabled":false,"onChange":{"action":"setState","key":"level","value":"{{ $event }}"}},{"cssClass":"text-muted-foreground","content":"{{ level | 'Drag the slider' }}","type":"Text"}]}}}>
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import Column, Slider, Text
from prefab_ui.actions import SetState

with Column(gap=4):
    Slider(
        value=50,
        on_change=SetState("level", "{{ $event }}"),
    )
    Text(
        "{{ level | 'Drag the slider' }}",
        css_class="text-muted-foreground",
    )
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "cssClass": "gap-4",
    "type": "Column",
    "children": [
      {
        "type": "Slider",
        "min": 0,
        "max": 100,
        "value": 50.0,
        "disabled": false,
        "onChange": {
          "action": "setState",
          "key": "level",
          "value": "{{ $event }}"
        }
      },
      {
        "cssClass": "text-muted-foreground",
        "content": "{{ level | 'Drag the slider' }}",
        "type": "Text"
      }
    ]
  }
}
```
</CodeGroup>
</ComponentPreview>

<Tip>
For simply displaying the slider's current value, [auto-binding with `name`](#displaying-the-value) is usually easier. Use `on_change` when you need to run custom logic like triggering a tool call or updating multiple state keys.
</Tip>

## Disabled State

<ComponentPreview json={{"view":{"type":"Slider","min":0,"max":100,"value":30.0,"disabled":true}}}>
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import Slider

Slider(value=30, disabled=True)
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "type": "Slider",
    "min": 0,
    "max": 100,
    "value": 30.0,
    "disabled": true
  }
}
```
</CodeGroup>
</ComponentPreview>

## API Reference

<Card icon="code" title="Slider Parameters">

<ParamField body="value" type="float | None" default="None">
  Initial value of the slider.
</ParamField>

<ParamField body="name" type="str | None" default="None">
  State key for the slider's current value. Set this to bind the slider to state for display or form submission.
</ParamField>

<ParamField body="min" type="float" default="0">
  Minimum value of the range.
</ParamField>

<ParamField body="max" type="float" default="100">
  Maximum value of the range.
</ParamField>

<ParamField body="step" type="float | None" default="None">
  Step increment. If not provided, the slider moves continuously.
</ParamField>

<ParamField body="disabled" type="bool" default="False">
  Whether the slider is non-interactive.
</ParamField>

<ParamField body="on_change" type="Action | list[Action] | None" default="None">
  Action(s) to execute when the value changes. `$event` is the current numeric value.
</ParamField>

<ParamField body="css_class" type="str | None" default="None">
  Additional Tailwind CSS classes appended to the component's built-in styles.
</ParamField>
</Card>

## Protocol Reference

```json Slider
{
  "type": "Slider",
  "min?": 0,
  "max?": 100,
  "value?": "number",
  "step?": "number",
  "name?": "string",
  "disabled?": false,
  "onChange?": "Action | Action[]",
  "cssClass?": "string"
}
```

For the complete protocol schema, see [Slider](/protocol/slider).
