Range Slider
daisyUI 5 の range class を wrap した <input type="range"> + ラベル/値表示/ヒント/エラーの chrome 付き。8 colors × 5 sizes、min/max/step、showValue (Alpine で live 表示)、error state。フォーム入力としても、純粋な視覚スライダーとしても使える。
値をライブ表示 (Alpine 駆動)
<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_6a7e9b508c320" 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_6a7e9b508c320" 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
<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_6a7e9b5090613" 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_6a7e9b5090613" 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_6a7e9b5090664" 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_6a7e9b5090664" 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_6a7e9b50906ab" 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_6a7e9b50906ab" 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_6a7e9b50906ef" 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_6a7e9b50906ef" 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_6a7e9b5090732" 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_6a7e9b5090732" 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_6a7e9b5090772" 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_6a7e9b5090772" 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_6a7e9b50907b4" 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_6a7e9b50907b4" 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_6a7e9b50907f4" 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_6a7e9b50907f4" 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
<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_6a7e9b50aa143" 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_6a7e9b50aa143" 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_6a7e9b50aa196" 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_6a7e9b50aa196" 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_6a7e9b50aa1dd" 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_6a7e9b50aa1dd" 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_6a7e9b50aa220" 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_6a7e9b50aa220" 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_6a7e9b50aa263" 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_6a7e9b50aa263" 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
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_6a7e9b50ba478" 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_6a7e9b50ba478" 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 が 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_6a7e9b50bed32" class="block text-[length:var(--text-field-sm)] font-medium text-error">Risk tolerance</label>
</div><input type="range" id="risk_6a7e9b50bed32" 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_6a7e9b50c2f1c" class="block text-[length:var(--text-field-sm)] font-medium text-base-content">Read only</label>
</div><input type="range" id="range_6a7e9b50c2f1c" 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_6a7e9b50c6e9d" 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:* は input に forwarding
<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_6a7e9b50c9913" 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>