---
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":{"name":"slider_2","type":"Slider","min":0,"max":100,"value":50.0,"disabled":false},"state":{"slider_2":50.0}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgU2xpZGVyCgpTbGlkZXIodmFsdWU9NTApCg==">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import Slider

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

## Displaying the Value

Create the slider with `defer=True` to get a reference to it, then use `.rx` to bind its value into a label. Call `insert()` to place the slider in the tree:

<ComponentPreview json={{"view":{"cssClass":"gap-2","type":"Column","children":[{"cssClass":"justify-between","type":"Row","children":[{"type":"Label","text":"Volume"},{"content":"{{ slider_3 | percent }}","bold":true,"type":"Text"}]},{"name":"slider_3","type":"Slider","min":0.0,"max":1.0,"value":0.75,"disabled":false}]},"state":{"slider_3":0.75}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgKAogICAgQ29sdW1uLAogICAgTGFiZWwsCiAgICBSb3csCiAgICBTbGlkZXIsCiAgICBUZXh0LAogICAgaW5zZXJ0LAopCgp2b2x1bWUgPSBTbGlkZXIodmFsdWU9MC43NSwgbWluPTAsIG1heD0xLCBkZWZlcj1UcnVlKQoKd2l0aCBDb2x1bW4oZ2FwPTIpOgogICAgd2l0aCBSb3coY3NzX2NsYXNzPSJqdXN0aWZ5LWJldHdlZW4iKToKICAgICAgICBMYWJlbCgiVm9sdW1lIikKICAgICAgICBUZXh0KGYie3ZvbHVtZS5yeC5wZXJjZW50KCl9IiwgYm9sZD1UcnVlKQogICAgaW5zZXJ0KHZvbHVtZSkK">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import (
    Column,
    Label,
    Row,
    Slider,
    Text,
    insert,
)

volume = Slider(value=0.75, min=0, max=1, defer=True)

with Column(gap=2):
    with Row(css_class="justify-between"):
        Label("Volume")
        Text(f"{volume.rx.percent()}", bold=True)
    insert(volume)
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "cssClass": "gap-2",
    "type": "Column",
    "children": [
      {
        "cssClass": "justify-between",
        "type": "Row",
        "children": [
          {"type": "Label", "text": "Volume"},
          {"content": "{{ slider_3 | percent }}", "bold": true, "type": "Text"}
        ]
      },
      {
        "name": "slider_3",
        "type": "Slider",
        "min": 0.0,
        "max": 1.0,
        "value": 0.75,
        "disabled": false
      }
    ]
  },
  "state": {"slider_3": 0.75}
}
```
</CodeGroup>
</ComponentPreview>

The `.number()` pipe strips trailing decimals so the display stays clean. `defer=True` prevents the slider from auto-attaching, letting you reference `.rx` before placing it with `insert()`.

## Range and Step

Use `min`, `max`, and `step` to constrain the slider. Here the range is 0–5 with half-step 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"}]},{"name":"rating","type":"Slider","min":0.0,"max":5.0,"value":4.0,"step":0.5,"disabled":false}]},"state":{"rating":4.0}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgKAogICAgQ29sdW1uLAogICAgTGFiZWwsCiAgICBSb3csCiAgICBTbGlkZXIsCiAgICBUZXh0LAogICAgaW5zZXJ0LAopCgpyYXRpbmcgPSBTbGlkZXIodmFsdWU9NCwgbmFtZT0icmF0aW5nIiwgbWluPTAsIG1heD01LCBzdGVwPTAuNSwgZGVmZXI9VHJ1ZSkKCndpdGggQ29sdW1uKGdhcD0yKToKICAgIHdpdGggUm93KGNzc19jbGFzcz0ianVzdGlmeS1iZXR3ZWVuIik6CiAgICAgICAgTGFiZWwoIlJhdGluZyIpCiAgICAgICAgVGV4dChyYXRpbmcucngsIGJvbGQ9VHJ1ZSkKICAgIGluc2VydChyYXRpbmcpCg==">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import (
    Column,
    Label,
    Row,
    Slider,
    Text,
    insert,
)

rating = Slider(value=4, name="rating", min=0, max=5, step=0.5, defer=True)

with Column(gap=2):
    with Row(css_class="justify-between"):
        Label("Rating")
        Text(rating.rx, bold=True)
    insert(rating)
```
```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"}
        ]
      },
      {
        "name": "rating",
        "type": "Slider",
        "min": 0.0,
        "max": 5.0,
        "value": 4.0,
        "step": 0.5,
        "disabled": false
      }
    ]
  },
  "state": {"rating": 4.0}
}
```
</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":[{"name":"slider_4","type":"Slider","min":0,"max":100,"value":50.0,"disabled":false,"onChange":{"action":"setState","key":"level","value":"{{ $event }}"}},{"cssClass":"text-muted-foreground","content":"{{ level | default:'Drag the slider' }}","type":"Text"}]},"state":{"slider_4":50.0}}} playground="ZnJvbSBwcmVmYWJfdWkuYWN0aW9ucyBpbXBvcnQgU2V0U3RhdGUKZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgQ29sdW1uLCBSeCwgU2xpZGVyLCBUZXh0CgpsZXZlbCA9IFJ4KCJsZXZlbCIpCgp3aXRoIENvbHVtbihnYXA9NCk6CiAgICBTbGlkZXIoCiAgICAgICAgdmFsdWU9NTAsCiAgICAgICAgb25fY2hhbmdlPVNldFN0YXRlKCJsZXZlbCIsIFJ4KCIkZXZlbnQiKSksCiAgICApCiAgICBUZXh0KAogICAgICAgIGxldmVsLmRlZmF1bHQoIkRyYWcgdGhlIHNsaWRlciIpLAogICAgICAgIGNzc19jbGFzcz0idGV4dC1tdXRlZC1mb3JlZ3JvdW5kIiwKICAgICkK">
<CodeGroup>
```python Python icon="python"
from prefab_ui.actions import SetState
from prefab_ui.components import Column, Rx, Slider, Text

level = Rx("level")

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

<Tip>
For simply displaying the slider's current value, [`.rx` binding](#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":{"name":"slider_5","type":"Slider","min":0,"max":100,"value":30.0,"disabled":true},"state":{"slider_5":30.0}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgU2xpZGVyCgpTbGlkZXIodmFsdWU9MzAsIGRpc2FibGVkPVRydWUpCg==">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import Slider

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

## Variants

Semantic variants color the filled track to communicate meaning at a glance — the same palette available on Progress:

<ComponentPreview json={{"view":{"cssClass":"gap-4","type":"Column","children":[{"cssClass":"gap-2","type":"Column","children":[{"type":"Label","text":"Default"},{"name":"slider_6","type":"Slider","min":0,"max":100,"value":60.0,"disabled":false}]},{"cssClass":"gap-2","type":"Column","children":[{"type":"Label","text":"Success"},{"name":"slider_7","type":"Slider","min":0,"max":100,"value":100.0,"disabled":false,"variant":"success"}]},{"cssClass":"gap-2","type":"Column","children":[{"type":"Label","text":"Warning"},{"name":"slider_8","type":"Slider","min":0,"max":100,"value":72.0,"disabled":false,"variant":"warning"}]},{"cssClass":"gap-2","type":"Column","children":[{"type":"Label","text":"Destructive"},{"name":"slider_9","type":"Slider","min":0,"max":100,"value":90.0,"disabled":false,"variant":"destructive"}]},{"cssClass":"gap-2","type":"Column","children":[{"type":"Label","text":"Info"},{"name":"slider_10","type":"Slider","min":0,"max":100,"value":45.0,"disabled":false,"variant":"info"}]},{"cssClass":"gap-2","type":"Column","children":[{"type":"Label","text":"Muted"},{"name":"slider_11","type":"Slider","min":0,"max":100,"value":30.0,"disabled":false,"variant":"muted"}]}]},"state":{"slider_6":60.0,"slider_7":100.0,"slider_8":72.0,"slider_9":90.0,"slider_10":45.0,"slider_11":30.0}}} playground=" ">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import Column, Label, Slider

with Column(gap=4):
    with Column(gap=2):
        Label("Default")
        Slider(value=60)
    with Column(gap=2):
        Label("Success")
        Slider(value=100, variant="success")
    with Column(gap=2):
        Label("Warning")
        Slider(value=72, variant="warning")
    with Column(gap=2):
        Label("Destructive")
        Slider(value=90, variant="destructive")
    with Column(gap=2):
        Label("Info")
        Slider(value=45, variant="info")
    with Column(gap=2):
        Label("Muted")
        Slider(value=30, variant="muted")
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "cssClass": "gap-4",
    "type": "Column",
    "children": [
      {
        "cssClass": "gap-2",
        "type": "Column",
        "children": [
          {"type": "Label", "text": "Default"},
          {
            "name": "slider_6",
            "type": "Slider",
            "min": 0,
            "max": 100,
            "value": 60.0,
            "disabled": false
          }
        ]
      },
      {
        "cssClass": "gap-2",
        "type": "Column",
        "children": [
          {"type": "Label", "text": "Success"},
          {
            "name": "slider_7",
            "type": "Slider",
            "min": 0,
            "max": 100,
            "value": 100.0,
            "disabled": false,
            "variant": "success"
          }
        ]
      },
      {
        "cssClass": "gap-2",
        "type": "Column",
        "children": [
          {"type": "Label", "text": "Warning"},
          {
            "name": "slider_8",
            "type": "Slider",
            "min": 0,
            "max": 100,
            "value": 72.0,
            "disabled": false,
            "variant": "warning"
          }
        ]
      },
      {
        "cssClass": "gap-2",
        "type": "Column",
        "children": [
          {"type": "Label", "text": "Destructive"},
          {
            "name": "slider_9",
            "type": "Slider",
            "min": 0,
            "max": 100,
            "value": 90.0,
            "disabled": false,
            "variant": "destructive"
          }
        ]
      },
      {
        "cssClass": "gap-2",
        "type": "Column",
        "children": [
          {"type": "Label", "text": "Info"},
          {
            "name": "slider_10",
            "type": "Slider",
            "min": 0,
            "max": 100,
            "value": 45.0,
            "disabled": false,
            "variant": "info"
          }
        ]
      },
      {
        "cssClass": "gap-2",
        "type": "Column",
        "children": [
          {"type": "Label", "text": "Muted"},
          {
            "name": "slider_11",
            "type": "Slider",
            "min": 0,
            "max": 100,
            "value": 30.0,
            "disabled": false,
            "variant": "muted"
          }
        ]
      }
    ]
  },
  "state": {
    "slider_6": 60.0,
    "slider_7": 100.0,
    "slider_8": 72.0,
    "slider_9": 90.0,
    "slider_10": 45.0,
    "slider_11": 30.0
  }
}
```
</CodeGroup>
</ComponentPreview>

## Custom Colors

Use `indicator_class` for arbitrary track colors beyond the built-in variants:

<ComponentPreview json={{"view":{"cssClass":"gap-4","type":"Column","children":[{"cssClass":"gap-2","type":"Column","children":[{"type":"Label","text":"Storage Used"},{"name":"slider_12","type":"Slider","min":0,"max":100,"value":85.0,"disabled":false,"indicatorClass":"bg-red-500"}]},{"cssClass":"gap-2","type":"Column","children":[{"type":"Label","text":"Upload Progress"},{"name":"slider_13","type":"Slider","min":0,"max":100,"value":45.0,"disabled":false,"indicatorClass":"bg-blue-500"}]}]},"state":{"slider_12":85.0,"slider_13":45.0}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgQ29sdW1uLCBMYWJlbCwgU2xpZGVyCgp3aXRoIENvbHVtbihnYXA9NCk6CiAgICB3aXRoIENvbHVtbihnYXA9Mik6CiAgICAgICAgTGFiZWwoIlN0b3JhZ2UgVXNlZCIpCiAgICAgICAgU2xpZGVyKHZhbHVlPTg1LCBpbmRpY2F0b3JfY2xhc3M9ImJnLXJlZC01MDAiKQogICAgd2l0aCBDb2x1bW4oZ2FwPTIpOgogICAgICAgIExhYmVsKCJVcGxvYWQgUHJvZ3Jlc3MiKQogICAgICAgIFNsaWRlcih2YWx1ZT00NSwgaW5kaWNhdG9yX2NsYXNzPSJiZy1ibHVlLTUwMCIpCg==">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import Column, Label, Slider

with Column(gap=4):
    with Column(gap=2):
        Label("Storage Used")
        Slider(value=85, indicator_class="bg-red-500")
    with Column(gap=2):
        Label("Upload Progress")
        Slider(value=45, indicator_class="bg-blue-500")
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "cssClass": "gap-4",
    "type": "Column",
    "children": [
      {
        "cssClass": "gap-2",
        "type": "Column",
        "children": [
          {"type": "Label", "text": "Storage Used"},
          {
            "name": "slider_12",
            "type": "Slider",
            "min": 0,
            "max": 100,
            "value": 85.0,
            "disabled": false,
            "indicatorClass": "bg-red-500"
          }
        ]
      },
      {
        "cssClass": "gap-2",
        "type": "Column",
        "children": [
          {"type": "Label", "text": "Upload Progress"},
          {
            "name": "slider_13",
            "type": "Slider",
            "min": 0,
            "max": 100,
            "value": 45.0,
            "disabled": false,
            "indicatorClass": "bg-blue-500"
          }
        ]
      }
    ]
  },
  "state": {"slider_12": 85.0, "slider_13": 45.0}
}
```
</CodeGroup>
</ComponentPreview>

## Vertical Orientation

Set `orientation="vertical"` for vertical sliders. They fill their container's height, so wrap them in a fixed-height parent:

<ComponentPreview json={{"view":{"cssClass":"gap-8 h-48 items-center justify-center","type":"Row","children":[{"name":"slider_14","type":"Slider","min":0,"max":100,"value":75.0,"disabled":false,"orientation":"vertical"},{"name":"slider_15","type":"Slider","min":0,"max":100,"value":50.0,"disabled":false,"variant":"success","orientation":"vertical"},{"name":"slider_16","type":"Slider","min":0,"max":100,"value":25.0,"disabled":false,"variant":"info","orientation":"vertical"}]},"state":{"slider_14":75.0,"slider_15":50.0,"slider_16":25.0}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgUm93LCBTbGlkZXIKCndpdGggUm93KGNzc19jbGFzcz0iZ2FwLTggaC00OCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIiKToKICAgIFNsaWRlcih2YWx1ZT03NSwgb3JpZW50YXRpb249InZlcnRpY2FsIikKICAgIFNsaWRlcih2YWx1ZT01MCwgb3JpZW50YXRpb249InZlcnRpY2FsIiwgdmFyaWFudD0ic3VjY2VzcyIpCiAgICBTbGlkZXIodmFsdWU9MjUsIG9yaWVudGF0aW9uPSJ2ZXJ0aWNhbCIsIHZhcmlhbnQ9ImluZm8iKQo=">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import Row, Slider

with Row(css_class="gap-8 h-48 items-center justify-center"):
    Slider(value=75, orientation="vertical")
    Slider(value=50, orientation="vertical", variant="success")
    Slider(value=25, orientation="vertical", variant="info")
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "cssClass": "gap-8 h-48 items-center justify-center",
    "type": "Row",
    "children": [
      {
        "name": "slider_14",
        "type": "Slider",
        "min": 0,
        "max": 100,
        "value": 75.0,
        "disabled": false,
        "orientation": "vertical"
      },
      {
        "name": "slider_15",
        "type": "Slider",
        "min": 0,
        "max": 100,
        "value": 50.0,
        "disabled": false,
        "variant": "success",
        "orientation": "vertical"
      },
      {
        "name": "slider_16",
        "type": "Slider",
        "min": 0,
        "max": 100,
        "value": 25.0,
        "disabled": false,
        "variant": "info",
        "orientation": "vertical"
      }
    ]
  },
  "state": {"slider_14": 75.0, "slider_15": 50.0, "slider_16": 25.0}
}
```
</CodeGroup>
</ComponentPreview>

## Handle Styles

The `handle_style` parameter changes the thumb shape. Use `"bar"` for a tall rounded rectangle instead of the default circle:

<ComponentPreview json={{"view":{"cssClass":"gap-4","type":"Column","children":[{"cssClass":"gap-2","type":"Column","children":[{"type":"Label","text":"Circle (default)"},{"name":"slider_17","type":"Slider","min":0,"max":100,"value":50.0,"disabled":false}]},{"cssClass":"gap-2","type":"Column","children":[{"type":"Label","text":"Bar"},{"name":"slider_18","type":"Slider","min":0,"max":100,"value":50.0,"disabled":false,"handleStyle":"bar"}]}]},"state":{"slider_17":50.0,"slider_18":50.0}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgQ29sdW1uLCBMYWJlbCwgU2xpZGVyCgp3aXRoIENvbHVtbihnYXA9NCk6CiAgICB3aXRoIENvbHVtbihnYXA9Mik6CiAgICAgICAgTGFiZWwoIkNpcmNsZSAoZGVmYXVsdCkiKQogICAgICAgIFNsaWRlcih2YWx1ZT01MCkKICAgIHdpdGggQ29sdW1uKGdhcD0yKToKICAgICAgICBMYWJlbCgiQmFyIikKICAgICAgICBTbGlkZXIodmFsdWU9NTAsIGhhbmRsZV9zdHlsZT0iYmFyIikK">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import Column, Label, Slider

with Column(gap=4):
    with Column(gap=2):
        Label("Circle (default)")
        Slider(value=50)
    with Column(gap=2):
        Label("Bar")
        Slider(value=50, handle_style="bar")
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "cssClass": "gap-4",
    "type": "Column",
    "children": [
      {
        "cssClass": "gap-2",
        "type": "Column",
        "children": [
          {"type": "Label", "text": "Circle (default)"},
          {
            "name": "slider_17",
            "type": "Slider",
            "min": 0,
            "max": 100,
            "value": 50.0,
            "disabled": false
          }
        ]
      },
      {
        "cssClass": "gap-2",
        "type": "Column",
        "children": [
          {"type": "Label", "text": "Bar"},
          {
            "name": "slider_18",
            "type": "Slider",
            "min": 0,
            "max": 100,
            "value": 50.0,
            "disabled": false,
            "handleStyle": "bar"
          }
        ]
      }
    ]
  },
  "state": {"slider_17": 50.0, "slider_18": 50.0}
}
```
</CodeGroup>
</ComponentPreview>

## Reading the Value

Use `.rx` to get a reactive reference to the slider's current numeric value. For a standard slider, `.rx` holds a single number; for a range slider (`range=True`), it holds a `[low, high]` array. The `.number()` pipe formats the value for clean display:

<ComponentPreview json={{"view":{"cssClass":"gap-4","type":"Column","children":[{"cssClass":"justify-between","type":"Row","children":[{"type":"Label","text":"Brightness"},{"content":"{{ slider_19 | percent }}","bold":true,"type":"Text"}]},{"type":"Progress","value":"{{ slider_19 }}","min":0,"max":100,"variant":"default"}]},"state":{"slider_19":0.42}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgQ29sdW1uLCBMYWJlbCwgUHJvZ3Jlc3MsIFJvdywgU2xpZGVyLCBUZXh0Cgp3aXRoIENvbHVtbihnYXA9NCk6CiAgICBzID0gU2xpZGVyKHZhbHVlPTAuNDIsIG1pbj0wLCBtYXg9MSwgZGVmZXI9VHJ1ZSkKICAgIHdpdGggUm93KGNzc19jbGFzcz0ianVzdGlmeS1iZXR3ZWVuIik6CiAgICAgICAgTGFiZWwoIkJyaWdodG5lc3MiKQogICAgICAgIFRleHQoZiJ7cy5yeC5wZXJjZW50KCl9IiwgYm9sZD1UcnVlKQogICAgUHJvZ3Jlc3ModmFsdWU9cy5yeCkK">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import Column, Label, Progress, Row, Slider, Text

with Column(gap=4):
    s = Slider(value=0.42, min=0, max=1, defer=True)
    with Row(css_class="justify-between"):
        Label("Brightness")
        Text(f"{s.rx.percent()}", bold=True)
    Progress(value=s.rx)
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "cssClass": "gap-4",
    "type": "Column",
    "children": [
      {
        "cssClass": "justify-between",
        "type": "Row",
        "children": [
          {"type": "Label", "text": "Brightness"},
          {"content": "{{ slider_19 | percent }}", "bold": true, "type": "Text"}
        ]
      },
      {
        "type": "Progress",
        "value": "{{ slider_19 }}",
        "min": 0,
        "max": 100,
        "variant": "default"
      }
    ]
  },
  "state": {"slider_19": 0.42}
}
```
</CodeGroup>
</ComponentPreview>

Drag the handle and both the percentage text and the progress bar update to reflect the slider's current position.

## 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="variant" type="str" default="default">
  Visual variant for the filled track: `"default"`, `"success"`, `"warning"`, `"destructive"`, `"info"`, `"muted"`.
</ParamField>

<ParamField body="indicator_class" type="str | None" default="None">
  Tailwind classes for the filled track. Overrides variant coloring.
</ParamField>

<ParamField body="orientation" type="str" default="horizontal">
  Layout direction: `"horizontal"` or `"vertical"`. Vertical sliders fill their container's height.
</ParamField>

<ParamField body="handle_style" type="str" default="circle">
  Thumb shape: `"circle"` (default round) or `"bar"` (tall rounded rectangle).
</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 | Action[]",
  "step?": "number",
  "range?": false,
  "name?": "string",
  "disabled?": false,
  "variant?": "default | success | warning | destructive | info | muted",
  "indicatorClass?": "string",
  "orientation?": "horizontal | vertical",
  "handleStyle?": "circle | bar",
  "onChange?": "Action | Action[]",
  "cssClass?": "string"
}
```

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