Slider
An input where the user selects a value from within a given range.
<div class="w-[60%] space-y-2">
<div class="flex justify-between">
<span class="text-sm font-medium">Value</span>
<span id="default-slider-value" class="text-sm text-muted-foreground">33</span>
</div>
<%= render Shadcn::SliderComponent.new(value: 33, data: { "output-target": "default-slider-value", "output-format": "{value}" }) %>
</div>
Installation
Add the component to your project:
rails generate shadcn:add slider
Usage
<div class="w-[60%] space-y-2">
<div class="flex justify-between">
<span class="text-sm font-medium">Value</span>
<span id="default-slider-value" class="text-sm text-muted-foreground">33</span>
</div>
<%= render Shadcn::SliderComponent.new(value: 33, data: { "output-target": "default-slider-value", "output-format": "{value}" }) %>
</div>
Examples
Default
<div class="w-[60%] space-y-2">
<div class="flex justify-between">
<span class="text-sm font-medium">Value</span>
<span id="default-slider-value" class="text-sm text-muted-foreground">33</span>
</div>
<%= render Shadcn::SliderComponent.new(value: 33, data: { "output-target": "default-slider-value", "output-format": "{value}" }) %>
</div>
With Synced Label
Use data-output-target and data-output-format to sync value labels.
<div class="space-y-4 w-full max-w-md">
<div class="flex justify-between">
<%= render Shadcn::LabelComponent.new { "Volume" } %>
<span id="volume-label" class="text-sm text-muted-foreground">75%</span>
</div>
<%= render Shadcn::SliderComponent.new(
value: 75,
max: 100,
data: { "output-target": "volume-label", "output-format": "{value}%" }
) %>
</div>
Two-Way Input Binding
Use data-input-target to bind a slider to a number input for two-way sync. Changes to either element update the other.
Change the slider or type a value in the input - both stay in sync.
<div class="space-y-4 w-full max-w-md">
<div class="flex items-center justify-between gap-4">
<%= render Shadcn::LabelComponent.new(for: "brightness-input") { "Brightness" } %>
<%= render Shadcn::InputComponent.new(
id: "brightness-input",
type: "number",
value: 75,
min: 0,
max: 100,
class_name: "w-20 text-center"
) %>
</div>
<%= render Shadcn::SliderComponent.new(
value: 75,
max: 100,
data: {
"input-target": "brightness-input"
}
) %>
<p class="text-xs text-muted-foreground">
Change the slider or type a value in the input - both stay in sync.
</p>
</div>
Custom Range
Use min and max to set a custom range.
<div class="space-y-4 w-full max-w-md">
<div class="flex justify-between">
<%= render Shadcn::LabelComponent.new { "Temperature" } %>
<span id="temp-label" class="text-sm text-muted-foreground">20°C</span>
</div>
<%= render Shadcn::SliderComponent.new(value: 20, min: 10, max: 30, data: { "output-target": "temp-label", "output-format": "{value}°C" }) %>
<div class="flex justify-between text-xs text-muted-foreground">
<span>10°C</span>
<span>30°C</span>
</div>
</div>
With Steps
Use step to set discrete intervals.
<div class="space-y-4 w-full max-w-md">
<div class="flex justify-between">
<%= render Shadcn::LabelComponent.new { "Rating" } %>
<span id="rating-label" class="text-sm text-muted-foreground">3 stars</span>
</div>
<%= render Shadcn::SliderComponent.new(value: 3, min: 1, max: 5, step: 1, data: { "output-target": "rating-label", "output-format": "{value} stars" }) %>
<div class="flex justify-between text-xs text-muted-foreground">
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
</div>
</div>
Decimal Steps
Use decimal values for step for fine-grained control.
<div class="space-y-4 w-full max-w-md">
<div class="flex justify-between">
<%= render Shadcn::LabelComponent.new { "Opacity" } %>
<span id="opacity-label" class="text-sm text-muted-foreground">0.5</span>
</div>
<%= render Shadcn::SliderComponent.new(value: 0.5, min: 0, max: 1, step: 0.1, data: { "output-target": "opacity-label", "output-format": "{value}" }) %>
<div class="flex justify-between text-xs text-muted-foreground">
<span>0</span>
<span>0.5</span>
<span>1</span>
</div>
</div>
Disabled
<div class="space-y-4 w-full max-w-md">
<%= render Shadcn::LabelComponent.new { "Disabled Slider" } %>
<%= render Shadcn::SliderComponent.new(value: 50, disabled: true) %>
</div>
In a Form
Audio Settings
Adjust your audio preferences.
<%= render Shadcn::CardComponent.new(class_name: "w-full max-w-md") do |card| %>
<% card.with_header do |header| %>
<% header.with_title { "Audio Settings" } %>
<% header.with_description { "Adjust your audio preferences." } %>
<% end %>
<% card.with_content do %>
<div class="space-y-6">
<div class="space-y-2">
<div class="flex justify-between">
<%= render Shadcn::LabelComponent.new { "Master Volume" } %>
<span id="master-vol-label" class="text-sm text-muted-foreground">80%</span>
</div>
<%= render Shadcn::SliderComponent.new(name: "master_volume", value: 80, data: { "output-target": "master-vol-label", "output-format": "{value}%" }) %>
</div>
<div class="space-y-2">
<div class="flex justify-between">
<%= render Shadcn::LabelComponent.new { "Music" } %>
<span id="music-vol-label" class="text-sm text-muted-foreground">60%</span>
</div>
<%= render Shadcn::SliderComponent.new(name: "music_volume", value: 60, data: { "output-target": "music-vol-label", "output-format": "{value}%" }) %>
</div>
<div class="space-y-2">
<div class="flex justify-between">
<%= render Shadcn::LabelComponent.new { "Sound Effects" } %>
<span id="sfx-vol-label" class="text-sm text-muted-foreground">90%</span>
</div>
<%= render Shadcn::SliderComponent.new(name: "sfx_volume", value: 90, data: { "output-target": "sfx-vol-label", "output-format": "{value}%" }) %>
</div>
</div>
<% end %>
<% card.with_footer do %>
<%= render Shadcn::ButtonComponent.new { "Save Settings" } %>
<% end %>
<% end %>
Rating
<%= render Shadcn::SliderComponent.new( name: "rating", value: 3, min: 1, max: 5, step: 1 ) %>
Volume Control
<%= render Shadcn::SliderComponent.new( name: "volume", value: 75, min: 0, max: 100, step: 5 ) %>
Temperature
<%= render Shadcn::SliderComponent.new( name: "temperature", value: 20.5, min: 15.0, max: 30.0, step: 0.5 ) %>
With Label
<%= render Shadcn::SliderComponent.new(name: "volume", value: 50, max: 100) %>
API Reference
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| name |
String
|
nil
|
Input name for form submission |
| value |
Numeric
|
0
|
Current slider value |
| min |
Numeric
|
0
|
Minimum value |
| max |
Numeric
|
100
|
Maximum value |
| step |
Numeric
|
1
|
Step increment |
| disabled |
Boolean
|
false
|
Whether the slider is disabled |
| class_name |
String
|
nil
|
Additional CSS classes to apply |
Stimulus Controller
This component requires JavaScript. The Stimulus controller shadcn--slider provides interactivity.
Updates the slider's visual fill and supports one-way output sync and two-way input binding.
Installation
Add to your config/importmap.rb:
pin "shadcn", to: "index.esm.js"
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
npm install shadcn-rails-stimulus
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails-stimulus"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
yarn add shadcn-rails-stimulus
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails-stimulus"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
npm install shadcn-rails-stimulus
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails-stimulus"
const application = Application.start()
registerShadcnControllers(application)
Or import just this controller:
import SliderController from "shadcn-rails-stimulus/controllers/slider_controller"
application.register("shadcn--slider", SliderController)
Targets
| Name | Description |
|---|---|
| output | Element to display the current value (auto-synced on change) |
Values
| Name | Type | Default | Description |
|---|---|---|---|
| outputFormat | String |
"{value}"
|
Format string for output ({value} and {percent} placeholders) |
Actions
| Action | Description |
|---|---|
| updateStyle | Updates CSS fill, syncs output target, and updates linked input on change |
TypeScript
Type definitions are included. Import types as needed:
import type { SliderController } from "shadcn-rails-stimulus"
Data Attributes
These attributes can be added to the slider's native <input type="range"> element:
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| data-output-target |
String
|
nil
|
ID of element to display value (one-way: slider → output) |
| data-output-format |
String
|
{value}
|
Format string with {value} and {percent} placeholders |
| data-input-target |
String
|
nil
|
ID of input element for two-way binding (slider ↔ input) |
Accessibility
- Uses native
<input type="range">for built-in accessibility - Keyboard navigation: Arrow keys to adjust value
- Always pair with a visible label or
aria-label - Consider showing the current value for screen readers
On This Page