shshadcn-htmx

Components

Slider

Native <input type="range"> styled with Tailwind. ARIA role / value attributes + the full keyboard contract (arrows, Home/End, PageUp/Down) come from the platform.

Installation

1. Install via the shadcn CLI

npx shadcn@latest add http://localhost/r/slider.json

2. Use it

components/ui/slider.tsx
import { Slider } from "@/components/ui/slider"

<Slider name="volume" value={50} ariaLabel="Volume" />
Or copy the source manually
components/ui/slider.tsx
/** @jsxImportSource hono/jsx */
import { cn, type ClassValue } from "@/registry/lib/cn"

// Slider — shadcn-htmx, htmx v4 + Tailwind v4.
//
// Built on native <input type="range">. The platform gives us:
//   - role="slider" implicit
//   - aria-valuemin / aria-valuemax / aria-valuenow auto-managed from
//     the min/max/value attributes — no manual ARIA needed
//   - Arrow keys, Home/End, PageUp/Down keyboard contract
//   - Focus ring, disabled state
//
// We restyle the track + thumb via Tailwind v4's [&::-webkit-slider-thumb]
// and [&::-moz-range-thumb] selectors (cross-browser). Both Chromium
// (-webkit-) and Firefox (-moz-) need separate rules.
//
// Refs:
//   repos/mdn/files/en-us/web/html/reference/elements/input/range/index.md
//   repos/mdn/files/en-us/web/accessibility/aria/reference/roles/slider_role/

type SliderProps = {
  id?: string
  name?: string
  value?: number
  min?: number
  max?: number
  // step="any" means no stepping — any value is allowed (barring min/max),
  // giving a continuous range. See MDN input/range "Setting step to any".
  step?: number | "any"
  disabled?: boolean
  required?: boolean
  // The full <input> form-attr family.
  form?: string
  list?: string
  // ARIA / labelling.
  ariaLabel?: string
  ariaLabelledby?: string
  ariaDescribedby?: string
  // Tooltip-ish announcement for AT — e.g. "$24 / month" instead of "24".
  ariaValuetext?: string
  class?: ClassValue
  // htmx passthrough (e.g. push the new value to the server on change).
  [key: `hx-${string}`]: any
  [key: `data-${string}`]: any
}

export function Slider(props: SliderProps) {
  const {
    id,
    name,
    value,
    min = 0,
    max = 100,
    step,
    disabled,
    required,
    form,
    list,
    ariaLabel,
    ariaLabelledby,
    ariaDescribedby,
    ariaValuetext,
    class: className,
    ...rest
  } = props
  return (
    <span
      data-slot="slider"
      data-disabled={disabled ? "true" : undefined}
      class={cn(
        "relative flex w-full touch-none items-center select-none",
        disabled && "opacity-50",
        className,
      )}
    >
      <input
        type="range"
        id={id}
        name={name}
        value={value}
        min={min}
        max={max}
        step={step}
        disabled={disabled}
        required={required}
        form={form}
        list={list}
        aria-label={ariaLabel}
        aria-labelledby={ariaLabelledby}
        aria-describedby={ariaDescribedby}
        aria-valuetext={ariaValuetext}
        class={cn(
          // Hide the default platform appearance so we can style the
          // track + thumb ourselves.
          "h-2 w-full cursor-pointer appearance-none bg-transparent outline-none",
          "[&::-webkit-slider-runnable-track]:h-1.5 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-muted",
          "[&::-moz-range-track]:h-1.5 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-muted",
          // Thumb: round, sized, bordered. -webkit needs margin-top to
          // recentre on the track; -moz centers automatically.
          "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:-mt-1 [&::-webkit-slider-thumb]:size-4 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary [&::-webkit-slider-thumb]:bg-background [&::-webkit-slider-thumb]:shadow-sm",
          "[&::-moz-range-thumb]:size-4 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary [&::-moz-range-thumb]:bg-background [&::-moz-range-thumb]:shadow-sm",
          // Focus ring on the thumb when keyboard-focused.
          "focus-visible:[&::-webkit-slider-thumb]:ring-[3px] focus-visible:[&::-webkit-slider-thumb]:ring-ring/50",
          "focus-visible:[&::-moz-range-thumb]:shadow-[0_0_0_3px_color-mix(in_oklch,var(--color-ring)_50%,transparent)]",
          // Disabled
          "disabled:cursor-not-allowed",
        )}
        {...rest}
      />
    </span>
  )
}

1. Save the file

Copy slider.html into templates/components/.

2. Use it

templates/components/slider.html
{% from "components/slider.html" import slider %}

{{ slider(name="volume", value=50, aria_label="Volume") }}
View source
templates/components/slider.html
{# Slider macro — shadcn-htmx, htmx v4 + Tailwind v4.
   Mirrors registry/ui/slider.tsx. Native <input type="range"> styled. #}

{% macro slider(
    id=none, name=none, value=none, min=0, max=100, step=none,
    disabled=false, required=false, form=none, list=none,
    aria_label=none, aria_labelledby=none, aria_describedby=none, aria_valuetext=none,
    extra_class="", **attrs
) %}
<span data-slot="slider"
      {%- if disabled %} data-disabled="true"{% endif %}
      class="relative flex w-full touch-none items-center select-none {% if disabled %}opacity-50{% endif %} {{ extra_class }}">
  <input type="range"
    {%- if id %} id="{{ id }}"{% endif %}
    {%- if name %} name="{{ name }}"{% endif %}
    {%- if value is not none %} value="{{ value }}"{% endif %}
    min="{{ min }}" max="{{ max }}"
    {# step may be a number or the special string "any" (continuous range) MDN input/range. #}
    {%- if step %} step="{{ step }}"{% endif %}
    {%- if disabled %} disabled{% endif %}
    {%- if required %} required{% endif %}
    {%- if form %} form="{{ form }}"{% endif %}
    {%- if list %} list="{{ list }}"{% endif %}
    {%- if aria_label %} aria-label="{{ aria_label }}"{% endif %}
    {%- if aria_labelledby %} aria-labelledby="{{ aria_labelledby }}"{% endif %}
    {%- if aria_describedby %} aria-describedby="{{ aria_describedby }}"{% endif %}
    {%- if aria_valuetext %} aria-valuetext="{{ aria_valuetext }}"{% endif %}
    class="h-2 w-full cursor-pointer appearance-none bg-transparent outline-none
           [&::-webkit-slider-runnable-track]:h-1.5 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-muted
           [&::-moz-range-track]:h-1.5 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-muted
           [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:-mt-1 [&::-webkit-slider-thumb]:size-4 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary [&::-webkit-slider-thumb]:bg-background [&::-webkit-slider-thumb]:shadow-sm
           [&::-moz-range-thumb]:size-4 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary [&::-moz-range-thumb]:bg-background [&::-moz-range-thumb]:shadow-sm
           focus-visible:[&::-webkit-slider-thumb]:ring-[3px] focus-visible:[&::-webkit-slider-thumb]:ring-ring/50 focus-visible:[&::-moz-range-thumb]:shadow-[0_0_0_3px_color-mix(in_oklch,var(--color-ring)_50%,transparent)]
           disabled:cursor-not-allowed"
    {%- for k, v in attrs.items() %} {{ k|replace('_', '-') }}="{{ v }}"{% endfor -%}
  >
</span>
{% endmacro %}

1. Save the file

Add slider.tmpl alongside button.tmpl.

2. Use it

templates/components/slider.tmpl
{{template "slider" (dict "Name" "volume" "Value" (ptr 50) "AriaLabel" "Volume")}}
View source
templates/components/slider.tmpl
{{/*
  Slider template — shadcn-htmx, htmx v4 + Tailwind v4.

      type SliderArgs struct {
          ID, Name, AriaLabel string
          AriaLabelledby, AriaDescribedby, AriaValuetext string
          Form, List string
          Value, Min, Max *int
          // Step is a string so it can hold a number ("0.5") or the special
          // value "any" (continuous range) — MDN input/range "Setting step to any".
          Step string
          Disabled, Required bool
          // Everything else (hx-get, hx-target, data-*, …) goes here.
          Attrs map[string]string
      }
*/}}
{{define "slider"}}
{{- $min := or .Min 0 -}}{{- $max := or .Max 100 -}}
<span data-slot="slider" {{if .Disabled}}data-disabled="true"{{end}}
      class="relative flex w-full touch-none items-center select-none {{if .Disabled}}opacity-50{{end}}">
  <input type="range"
    {{if .ID}}id="{{.ID}}"{{end}} {{if .Name}}name="{{.Name}}"{{end}}
    {{if .Value}}value="{{deref .Value}}"{{end}}
    min="{{$min}}" max="{{$max}}"
    {{if .Step}}step="{{.Step}}"{{end}}
    {{if .Disabled}}disabled{{end}} {{if .Required}}required{{end}}
    {{if .Form}}form="{{.Form}}"{{end}} {{if .List}}list="{{.List}}"{{end}}
    {{if .AriaLabel}}aria-label="{{.AriaLabel}}"{{end}}
    {{if .AriaLabelledby}}aria-labelledby="{{.AriaLabelledby}}"{{end}}
    {{if .AriaDescribedby}}aria-describedby="{{.AriaDescribedby}}"{{end}}
    {{if .AriaValuetext}}aria-valuetext="{{.AriaValuetext}}"{{end}}
    class="h-2 w-full cursor-pointer appearance-none bg-transparent outline-none [&::-webkit-slider-runnable-track]:h-1.5 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-muted [&::-moz-range-track]:h-1.5 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-muted [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:-mt-1 [&::-webkit-slider-thumb]:size-4 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary [&::-webkit-slider-thumb]:bg-background [&::-webkit-slider-thumb]:shadow-sm [&::-moz-range-thumb]:size-4 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary [&::-moz-range-thumb]:bg-background [&::-moz-range-thumb]:shadow-sm focus-visible:[&::-webkit-slider-thumb]:ring-[3px] focus-visible:[&::-webkit-slider-thumb]:ring-ring/50 disabled:cursor-not-allowed"
    {{- range $k, $v := .Attrs}} {{$k}}="{{$v}}"{{end -}}>
</span>
{{end}}

1. Save the file

Drop slider.ex into lib/my_app_web/components/.

2. Use it

lib/my_app_web/components/slider.ex
<.slider name="volume" value={50} aria-label="Volume" />
View source
lib/my_app_web/components/slider.ex
defmodule ShadcnHtmx.Components.Slider do
  @moduledoc """
  Slider — shadcn-htmx, htmx v4 + Tailwind v4 for Phoenix.

  Native `<input type="range">` styled via Tailwind. The platform handles
  role=slider, aria-valuemin/max/now, arrow/Home/End/PageUp/Down — we
  just provide the visual track + thumb.

  ## Examples

      <.slider name="volume" value={50} min={0} max={100} aria-label="Volume" />
  """

  use Phoenix.Component

  attr :id, :string, default: nil
  attr :name, :string, default: nil
  attr :value, :integer, default: nil
  attr :min, :integer, default: 0
  attr :max, :integer, default: 100
  # :any so step accepts a number or the special string "any" (continuous
  # range) — MDN input/range "Setting step to any".
  attr :step, :any, default: nil
  attr :disabled, :boolean, default: false
  attr :required, :boolean, default: false
  attr :class, :string, default: nil

  attr :rest, :global,
    include: ~w(form list aria-label aria-labelledby aria-describedby aria-valuetext)

  def slider(assigns) do
    ~H"""
    <span
      data-slot="slider"
      data-disabled={@disabled && "true"}
      class={[
        "relative flex w-full touch-none items-center select-none",
        @disabled && "opacity-50",
        @class
      ]}
    >
      <input
        type="range"
        id={@id}
        name={@name}
        value={@value}
        min={@min}
        max={@max}
        step={@step}
        disabled={@disabled}
        required={@required}
        class={[
          "h-2 w-full cursor-pointer appearance-none bg-transparent outline-none",
          "[&::-webkit-slider-runnable-track]:h-1.5 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-muted",
          "[&::-moz-range-track]:h-1.5 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-muted",
          "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:-mt-1 [&::-webkit-slider-thumb]:size-4 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary [&::-webkit-slider-thumb]:bg-background [&::-webkit-slider-thumb]:shadow-sm",
          "[&::-moz-range-thumb]:size-4 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary [&::-moz-range-thumb]:bg-background [&::-moz-range-thumb]:shadow-sm",
          "focus-visible:[&::-webkit-slider-thumb]:ring-[3px] focus-visible:[&::-webkit-slider-thumb]:ring-ring/50",
          "disabled:cursor-not-allowed"
        ]}
        {@rest}
      />
    </span>
    """
  end
end

1. Save the file

Tailwind utilities only; no JS.

2. Use it

index.html
<span data-slot="slider" class="…">
  <input type="range" name="volume" min="0" max="100" value="50"
         aria-label="Volume" class="…">
</span>
View source
index.html
<!--
  shadcn-htmx — raw HTML slider snippet.

  Native <input type="range"> with Tailwind utilities to style the
  track + thumb cross-browser. ARIA + keyboard are handled by the
  platform — no JS required.
-->

<span data-slot="slider" class="relative flex w-full touch-none items-center select-none">
  <input type="range" name="volume" min="0" max="100" value="50"
         aria-label="Volume"
         class="h-2 w-full cursor-pointer appearance-none bg-transparent outline-none
                [&::-webkit-slider-runnable-track]:h-1.5 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-muted
                [&::-moz-range-track]:h-1.5 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-muted
                [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:-mt-1 [&::-webkit-slider-thumb]:size-4 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary [&::-webkit-slider-thumb]:bg-background [&::-webkit-slider-thumb]:shadow-sm
                [&::-moz-range-thumb]:size-4 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary [&::-moz-range-thumb]:bg-background [&::-moz-range-thumb]:shadow-sm
                focus-visible:[&::-webkit-slider-thumb]:ring-[3px] focus-visible:[&::-webkit-slider-thumb]:ring-ring/50
                disabled:cursor-not-allowed">
</span>

Examples

Basic — keyboard works out of the box

Tab to focus, then ←/→ increments by step, Home/End jump to ends, PageUp/Down move in bigger steps.

Native <input type="range"> ships with the full APG slider keyboard contract. We add styling, not behaviour. If you need a vertical slider, set orient="vertical" (Firefox) or rotate visually via CSS transform.

<Label htmlFor="vol">Volume</Label>
<Slider id="vol" name="volume" value={50} ariaLabel="Volume" />
{{ label("Volume", for_="vol") }}
{{ slider(id="vol", name="volume", value=50, aria_label="Volume") }}
{{template "label" (dict "Text" "Volume" "For" "vol")}}
{{template "slider" (dict "ID" "vol" "Name" "volume" "Value" (ptr 50) "AriaLabel" "Volume")}}
<.label for="vol">Volume</.label>
<.slider id="vol" name="volume" value={50} aria-label="Volume" />
<div class="grid w-full max-w-md gap-2">
  <label for="ex-slider-vol" class="flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50" data-slot="label">Volume</label>
  <span data-slot="slider" class="relative flex w-full touch-none items-center select-none">
    <input type="range" id="ex-slider-vol" name="volume" value="50" min="0" max="100" aria-label="Volume" class="h-2 w-full cursor-pointer appearance-none bg-transparent outline-none [&amp;::-webkit-slider-runnable-track]:h-1.5 [&amp;::-webkit-slider-runnable-track]:rounded-full [&amp;::-webkit-slider-runnable-track]:bg-muted [&amp;::-moz-range-track]:h-1.5 [&amp;::-moz-range-track]:rounded-full [&amp;::-moz-range-track]:bg-muted [&amp;::-webkit-slider-thumb]:appearance-none [&amp;::-webkit-slider-thumb]:-mt-1 [&amp;::-webkit-slider-thumb]:size-4 [&amp;::-webkit-slider-thumb]:rounded-full [&amp;::-webkit-slider-thumb]:border-2 [&amp;::-webkit-slider-thumb]:border-primary [&amp;::-webkit-slider-thumb]:bg-background [&amp;::-webkit-slider-thumb]:shadow-sm [&amp;::-moz-range-thumb]:size-4 [&amp;::-moz-range-thumb]:rounded-full [&amp;::-moz-range-thumb]:border-2 [&amp;::-moz-range-thumb]:border-primary [&amp;::-moz-range-thumb]:bg-background [&amp;::-moz-range-thumb]:shadow-sm focus-visible:[&amp;::-webkit-slider-thumb]:ring-[3px] focus-visible:[&amp;::-webkit-slider-thumb]:ring-ring/50 focus-visible:[&amp;::-moz-range-thumb]:shadow-[0_0_0_3px_color-mix(in_oklch,var(--color-ring)_50%,transparent)] disabled:cursor-not-allowed"/>
  </span>
</div>

Custom range + step

Set min/max/step to constrain the slider. step also controls how much each Arrow press moves the value.

Use aria-valuetext when the visible value isn't self-explanatory. AT users hearing "24" don't know if that's dollars, months, or decibels — "$24 per month" is unambiguous.

<Slider id="price" min={0} max={500} step={25} value={250}
        ariaLabel="Monthly budget" ariaValuetext="$250 per month" />
{{ slider(id="price", min=0, max=500, step=25, value=250,
            aria_label="Monthly budget", aria_valuetext="$250 per month") }}
{{template "slider" (dict "ID" "price" "Min" (ptr 0) "Max" (ptr 500) "Step" (ptr 25) "Value" (ptr 250) "AriaLabel" "Monthly budget")}}
<.slider id="price" min={0} max={500} step={25} value={250}
         aria-label="Monthly budget" aria-valuetext="$250 per month" />
<div class="grid w-full max-w-md gap-2">
  <label for="ex-slider-price" class="flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50" data-slot="label">Monthly budget</label>
  <span data-slot="slider" class="relative flex w-full touch-none items-center select-none">
    <input type="range" id="ex-slider-price" name="budget" value="250" min="0" max="500" step="25" aria-label="Monthly budget" aria-valuetext="$250 per month" class="h-2 w-full cursor-pointer appearance-none bg-transparent outline-none [&amp;::-webkit-slider-runnable-track]:h-1.5 [&amp;::-webkit-slider-runnable-track]:rounded-full [&amp;::-webkit-slider-runnable-track]:bg-muted [&amp;::-moz-range-track]:h-1.5 [&amp;::-moz-range-track]:rounded-full [&amp;::-moz-range-track]:bg-muted [&amp;::-webkit-slider-thumb]:appearance-none [&amp;::-webkit-slider-thumb]:-mt-1 [&amp;::-webkit-slider-thumb]:size-4 [&amp;::-webkit-slider-thumb]:rounded-full [&amp;::-webkit-slider-thumb]:border-2 [&amp;::-webkit-slider-thumb]:border-primary [&amp;::-webkit-slider-thumb]:bg-background [&amp;::-webkit-slider-thumb]:shadow-sm [&amp;::-moz-range-thumb]:size-4 [&amp;::-moz-range-thumb]:rounded-full [&amp;::-moz-range-thumb]:border-2 [&amp;::-moz-range-thumb]:border-primary [&amp;::-moz-range-thumb]:bg-background [&amp;::-moz-range-thumb]:shadow-sm focus-visible:[&amp;::-webkit-slider-thumb]:ring-[3px] focus-visible:[&amp;::-webkit-slider-thumb]:ring-ring/50 focus-visible:[&amp;::-moz-range-thumb]:shadow-[0_0_0_3px_color-mix(in_oklch,var(--color-ring)_50%,transparent)] disabled:cursor-not-allowed"/>
  </span>
</div>

Further reading

Disabled

Disabled sliders are non-focusable and not draggable.

Disabled is the native attribute — the platform handles keyboard exclusion, mouse cursor, and removes the element from the tab order. We just dim the wrapper.

<Slider value={40} disabled ariaLabel="Disabled slider" />
{{ slider(value=40, disabled=true, aria_label="Disabled slider") }}
{{template "slider" (dict "Value" (ptr 40) "Disabled" true "AriaLabel" "Disabled slider")}}
<.slider value={40} disabled aria-label="Disabled slider" />
<div class="grid w-full max-w-md gap-2">
  <label for="ex-slider-disabled" class="flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50" data-slot="label">Disabled</label>
  <span data-slot="slider" data-disabled="true" class="relative flex w-full touch-none items-center select-none opacity-50">
    <input type="range" id="ex-slider-disabled" value="40" min="0" max="100" disabled="" aria-label="Disabled slider" class="h-2 w-full cursor-pointer appearance-none bg-transparent outline-none [&amp;::-webkit-slider-runnable-track]:h-1.5 [&amp;::-webkit-slider-runnable-track]:rounded-full [&amp;::-webkit-slider-runnable-track]:bg-muted [&amp;::-moz-range-track]:h-1.5 [&amp;::-moz-range-track]:rounded-full [&amp;::-moz-range-track]:bg-muted [&amp;::-webkit-slider-thumb]:appearance-none [&amp;::-webkit-slider-thumb]:-mt-1 [&amp;::-webkit-slider-thumb]:size-4 [&amp;::-webkit-slider-thumb]:rounded-full [&amp;::-webkit-slider-thumb]:border-2 [&amp;::-webkit-slider-thumb]:border-primary [&amp;::-webkit-slider-thumb]:bg-background [&amp;::-webkit-slider-thumb]:shadow-sm [&amp;::-moz-range-thumb]:size-4 [&amp;::-moz-range-thumb]:rounded-full [&amp;::-moz-range-thumb]:border-2 [&amp;::-moz-range-thumb]:border-primary [&amp;::-moz-range-thumb]:bg-background [&amp;::-moz-range-thumb]:shadow-sm focus-visible:[&amp;::-webkit-slider-thumb]:ring-[3px] focus-visible:[&amp;::-webkit-slider-thumb]:ring-ring/50 focus-visible:[&amp;::-moz-range-thumb]:shadow-[0_0_0_3px_color-mix(in_oklch,var(--color-ring)_50%,transparent)] disabled:cursor-not-allowed" data-test="disabled"/>
  </span>
</div>

API Reference

<Slider>

PropTypeDefaultDescription
liststring
Id of a <datalist> whose <option> values render tick marks on the track (e.g. temperature presets).MDNrange tick marks
minnumber0
Minimum value.
maxnumber100
Maximum value.
stepnumber
Increment per arrow press.
valuenumber
Current value.
ariaValuetextstring
Human-readable value (e.g. "$24 per month") for AT.MDNaria-valuetext
idstring
Pairs the input with a <label for>.
namestring
Form field name on submit.
requiredbooleanfalse
Native HTML required for form validation.
disabledbooleanfalse
Disable — unfocusable, not submitted.
ariaLabelstring
Accessible name when no visible <label>.MDNaria-label
ariaLabelledbystring
Id of a visible element providing the accessible name.MDNaria-labelledby
ariaDescribedbystring
Id of an element describing this control (announced after the name).MDNaria-describedby
classstring
Extra Tailwind classes appended to the root element.
hx-*any
Any htmx attribute. Forwarded onto the underlying element.htmxAttribute reference