Range Slider

Wrapped daisyUI 5 range class. <input type="range"> + chrome (label, value display, hint, error state). 8 colors × 5 sizes, min/max/step, showValue (Alpine live display), error state. Works as both form input and pure visual slider.

Live value display (Alpine-driven)

40
<x-range-slider name="volume" label="Volume" :value="40" showValue />
<div class="w-full" x-data="{ pct: 40, v: '40' }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="volume_6a7e9b64a0403" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Volume</label>
<span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums" x-text="v">40</span>
</div><input type="range" id="volume_6a7e9b64a0403" min="0" max="100" step="1" value="40" style="--range-fill: 40%" x-bind:style="'--range-fill: ' + pct + '%'" name="volume" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100)); v = $event.target.value" class="pn-range w-full pn-range-primary">
</div>

color — 8 colors

50
50
50
50
50
50
50
50
<x-range-slider color="primary" label="Primary" :value="50" showValue />
<x-range-slider color="secondary" label="Secondary" :value="50" showValue />
<x-range-slider color="accent" label="Accent" :value="50" showValue />
<x-range-slider color="neutral" label="Neutral" :value="50" showValue />
<x-range-slider color="info" label="Info" :value="50" showValue />
<x-range-slider color="success" label="Success" :value="50" showValue />
<x-range-slider color="warning" label="Warning" :value="50" showValue />
<x-range-slider color="error" label="Error" :value="50" showValue />
<div class="w-full" x-data="{ pct: 50, v: '50' }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="range_6a7e9b64a4757" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Primary</label>
<span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums" x-text="v">50</span>
</div><input type="range" id="range_6a7e9b64a4757" min="0" max="100" step="1" value="50" style="--range-fill: 50%" x-bind:style="'--range-fill: ' + pct + '%'" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100)); v = $event.target.value" class="pn-range w-full pn-range-primary">
</div>
<div class="w-full" x-data="{ pct: 50, v: '50' }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="range_6a7e9b64a47ad" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Secondary</label>
<span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums" x-text="v">50</span>
</div><input type="range" id="range_6a7e9b64a47ad" min="0" max="100" step="1" value="50" style="--range-fill: 50%" x-bind:style="'--range-fill: ' + pct + '%'" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100)); v = $event.target.value" class="pn-range w-full pn-range-secondary">
</div>
<div class="w-full" x-data="{ pct: 50, v: '50' }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="range_6a7e9b64a47f5" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Accent</label>
<span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums" x-text="v">50</span>
</div><input type="range" id="range_6a7e9b64a47f5" min="0" max="100" step="1" value="50" style="--range-fill: 50%" x-bind:style="'--range-fill: ' + pct + '%'" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100)); v = $event.target.value" class="pn-range w-full pn-range-accent">
</div>
<div class="w-full" x-data="{ pct: 50, v: '50' }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="range_6a7e9b64a483a" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Neutral</label>
<span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums" x-text="v">50</span>
</div><input type="range" id="range_6a7e9b64a483a" min="0" max="100" step="1" value="50" style="--range-fill: 50%" x-bind:style="'--range-fill: ' + pct + '%'" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100)); v = $event.target.value" class="pn-range w-full pn-range-neutral">
</div>
<div class="w-full" x-data="{ pct: 50, v: '50' }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="range_6a7e9b64a4880" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Info</label>
<span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums" x-text="v">50</span>
</div><input type="range" id="range_6a7e9b64a4880" min="0" max="100" step="1" value="50" style="--range-fill: 50%" x-bind:style="'--range-fill: ' + pct + '%'" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100)); v = $event.target.value" class="pn-range w-full pn-range-info">
</div>
<div class="w-full" x-data="{ pct: 50, v: '50' }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="range_6a7e9b64a48c3" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Success</label>
<span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums" x-text="v">50</span>
</div><input type="range" id="range_6a7e9b64a48c3" min="0" max="100" step="1" value="50" style="--range-fill: 50%" x-bind:style="'--range-fill: ' + pct + '%'" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100)); v = $event.target.value" class="pn-range w-full pn-range-success">
</div>
<div class="w-full" x-data="{ pct: 50, v: '50' }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="range_6a7e9b64a4906" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Warning</label>
<span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums" x-text="v">50</span>
</div><input type="range" id="range_6a7e9b64a4906" min="0" max="100" step="1" value="50" style="--range-fill: 50%" x-bind:style="'--range-fill: ' + pct + '%'" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100)); v = $event.target.value" class="pn-range w-full pn-range-warning">
</div>
<div class="w-full" x-data="{ pct: 50, v: '50' }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="range_6a7e9b64a4949" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Error</label>
<span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums" x-text="v">50</span>
</div><input type="range" id="range_6a7e9b64a4949" min="0" max="100" step="1" value="50" style="--range-fill: 50%" x-bind:style="'--range-fill: ' + pct + '%'" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100)); v = $event.target.value" class="pn-range w-full pn-range-error">
</div>

size — xs / sm / md (default) / lg / xl

60
60
60
60
60
<x-range-slider size="xs" label="xs" :value="60" showValue />
<x-range-slider size="sm" label="sm" :value="60" showValue />
<x-range-slider size="md" label="md (default)" :value="60" showValue />
<x-range-slider size="lg" label="lg" :value="60" showValue />
<x-range-slider size="xl" label="xl" :value="60" showValue />
<div class="w-full" x-data="{ pct: 60, v: '60' }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="range_6a7e9b64befda" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">xs</label>
<span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums" x-text="v">60</span>
</div><input type="range" id="range_6a7e9b64befda" min="0" max="100" step="1" value="60" style="--range-fill: 60%" x-bind:style="'--range-fill: ' + pct + '%'" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100)); v = $event.target.value" class="pn-range w-full pn-range-primary pn-range-xs">
</div>
<div class="w-full" x-data="{ pct: 60, v: '60' }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="range_6a7e9b64bf026" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">sm</label>
<span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums" x-text="v">60</span>
</div><input type="range" id="range_6a7e9b64bf026" min="0" max="100" step="1" value="60" style="--range-fill: 60%" x-bind:style="'--range-fill: ' + pct + '%'" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100)); v = $event.target.value" class="pn-range w-full pn-range-primary pn-range-sm">
</div>
<div class="w-full" x-data="{ pct: 60, v: '60' }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="range_6a7e9b64bf065" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">md (default)</label>
<span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums" x-text="v">60</span>
</div><input type="range" id="range_6a7e9b64bf065" min="0" max="100" step="1" value="60" style="--range-fill: 60%" x-bind:style="'--range-fill: ' + pct + '%'" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100)); v = $event.target.value" class="pn-range w-full pn-range-primary">
</div>
<div class="w-full" x-data="{ pct: 60, v: '60' }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="range_6a7e9b64bf0a4" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">lg</label>
<span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums" x-text="v">60</span>
</div><input type="range" id="range_6a7e9b64bf0a4" min="0" max="100" step="1" value="60" style="--range-fill: 60%" x-bind:style="'--range-fill: ' + pct + '%'" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100)); v = $event.target.value" class="pn-range w-full pn-range-primary pn-range-lg">
</div>
<div class="w-full" x-data="{ pct: 60, v: '60' }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="range_6a7e9b64bf0e0" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">xl</label>
<span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums" x-text="v">60</span>
</div><input type="range" id="range_6a7e9b64bf0e0" min="0" max="100" step="1" value="60" style="--range-fill: 60%" x-bind:style="'--range-fill: ' + pct + '%'" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100)); v = $event.target.value" class="pn-range w-full pn-range-primary pn-range-xl">
</div>

min / max / step

500

Steps of 50 between 0 and 1000

<x-range-slider name="price-cap" label="Max price" :min="0" :max="1000" :step="50" :value="500" showValue hint="Steps of 50 between 0 and 1000" />
<div class="w-full" x-data="{ pct: 50, v: '500' }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="price-cap_6a7e9b64cfb28" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Max price</label>
<span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums" x-text="v">500</span>
</div><input type="range" id="price-cap_6a7e9b64cfb28" min="0" max="1000" step="50" value="500" style="--range-fill: 50%" x-bind:style="'--range-fill: ' + pct + '%'" name="price-cap" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 1000) * 100)); v = $event.target.value" class="pn-range w-full pn-range-primary">
<div class="flex items-baseline justify-between mt-1">
<p class="text-[length:var(--text-field-sm)] text-base-content/50">
            Steps of 50 between 0 and 1000
        </p>
</div>
</div>

error state — label/hint switch to text-error

Maximum 80 allowed

<x-range-slider name="risk" label="Risk tolerance" :min="0" :max="100" :value="95" error="Maximum 80 allowed" />
<div class="w-full" x-data="{ pct: 95 }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="risk_6a7e9b64d4d44" class="block text-[length:var(--text-field-sm)] font-medium text-error">Risk tolerance</label>
</div><input type="range" id="risk_6a7e9b64d4d44" min="0" max="100" step="1" value="95" style="--range-fill: 95%" x-bind:style="'--range-fill: ' + pct + '%'" name="risk" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100))" class="pn-range w-full pn-range-primary">
<div class="flex items-baseline justify-between mt-1">
<p class="text-[length:var(--text-field-sm)] text-error">
            Maximum 80 allowed
        </p>
</div>
</div>

disabled

Disabled sliders cannot be dragged

<x-range-slider label="Read only" :value="35" hint="Disabled sliders cannot be dragged" disabled />
<div class="w-full" x-data="{ pct: 35 }">
<div class="flex items-baseline justify-between mb-1.5">
<label for="range_6a7e9b64d8fac" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Read only</label>
</div><input type="range" id="range_6a7e9b64d8fac" min="0" max="100" step="1" value="35" style="--range-fill: 35%" x-bind:style="'--range-fill: ' + pct + '%'" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100))" class="pn-range w-full pn-range-primary" disabled>
<div class="flex items-baseline justify-between mt-1">
<p class="text-[length:var(--text-field-sm)] text-base-content/50">
            Disabled sliders cannot be dragged
        </p>
</div>
</div>

no label / no chrome

<x-range-slider :value="70" />
<div class="w-full" x-data="{ pct: 70 }">
<input type="range" id="range_6a7e9b64dd080" min="0" max="100" step="1" value="70" style="--range-fill: 70%" x-bind:style="'--range-fill: ' + pct + '%'" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 0) / 100) * 100))" class="pn-range w-full pn-range-primary">
</div>

Livewire model — wire:* forwards to the input

120
<x-range-slider name="zoom" wire:model.live="zoom" :min="50" :max="200" :value="120" showValue />
<div class="w-full" x-data="{ pct: 46.666666666667, v: '120' }">
<input type="range" id="zoom_6a7e9b64dfca4" min="50" max="200" step="1" value="120" style="--range-fill: 46.666666666667%" x-bind:style="'--range-fill: ' + pct + '%'" name="zoom" x-on:input="pct = Math.max(0, Math.min(100, (($event.target.value - 50) / 150) * 100)); v = $event.target.value" wire:model.live="zoom" class="pn-range w-full pn-range-primary">
<div class="flex items-baseline justify-between mt-1">
<p class="text-[length:var(--text-field-sm)] text-base-content/50"></p><span class="text-[length:var(--text-field-xs)] text-base-content/70 tabular-nums shrink-0 ml-2" x-text="v">120</span>
</div>
</div>