<div class="w-full max-w-sm space-y-3">
<div class="flex justify-between items-center text-xs font-semibold text-foreground">
<span>Volume Level</span>
<span class="px-2 py-0.5 rounded-md bg-primary/10 text-primary font-mono font-bold">64%</span>
</div>
<input type="range" min="0" max="100" value="64" class="w-full h-2 bg-muted rounded-lg appearance-none cursor-pointer accent-primary" />
<div class="flex justify-between text-[10px] text-muted-foreground font-mono">
<span>0%</span>
<span>50%</span>
<span>100%</span>
</div>
</div>
import React from "react";
export function Slider({ value = 50, onChange }: { value?: number; onChange?: (val: number) => void }) {
return (
<div className="w-full max-w-sm space-y-2">
<input
type="range"
min="0"
max="100"
value={value}
onChange={(e) => onChange?.(Number(e.target.value))}
className="w-full h-2 bg-muted rounded-lg appearance-none cursor-pointer accent-primary"
/>
</div>
);
}
"use client";
import React, { useState } from "react";
export interface SliderProps {
label?: string;
min?: number;
max?: number;
step?: number;
defaultValue?: number;
unit?: string;
onChange?: (val: number) => void;
}
export default function Slider({
label = "Brightness Level",
min = 0,
max = 100,
step = 1,
defaultValue = 70,
unit = "%",
onChange,
}: SliderProps) {
const [val, setVal] = useState(defaultValue);
const percentage = ((val - min) / (max - min)) * 100;
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const next = Number(e.target.value);
setVal(next);
onChange?.(next);
};
return (
<div className="w-full max-w-sm space-y-3.5 p-4 rounded-2xl border border-border bg-card shadow-2xs">
<div className="flex justify-between items-center text-xs font-semibold text-foreground">
<span>{label}</span>
<span className="px-2.5 py-0.5 rounded-full bg-primary/10 text-primary font-mono font-bold text-xs">
{val}
{unit}
</span>
</div>
<div className="relative flex items-center">
<input
type="range"
min={min}
max={max}
step={step}
value={val}
onChange={handleChange}
style={{
background: `linear-gradient(to right, var(--color-primary, #6366f1) ${percentage}%, var(--color-muted, #e4e4e7) ${percentage}%)`,
}}
className="w-full h-2 rounded-lg appearance-none cursor-pointer accent-primary focus:outline-none focus:ring-2 focus:ring-primary/20"
/>
</div>
<div className="flex justify-between text-[11px] text-muted-foreground font-mono">
<span>
{min}
{unit}
</span>
<span>
{max / 2}
{unit}
</span>
<span>
{max}
{unit}
</span>
</div>
</div>
);
}
"use client";
import React, { useState } from "react";
import { motion } from "framer-motion";
import { Volume2, VolumeX } from "lucide-react";
export default function AnimatedSlider() {
const [value, setValue] = useState(55);
const [isHovered, setIsHovered] = useState(false);
return (
<div className="w-full max-w-sm p-6 rounded-2xl border border-border bg-card/70 backdrop-blur-md shadow-lg space-y-4">
<div className="flex items-center justify-between text-xs font-semibold text-foreground">
<div className="flex items-center gap-2">
{value === 0 ? (
<VolumeX className="h-4 w-4 text-muted-foreground" />
) : (
<Volume2 className="h-4 w-4 text-primary" />
)}
<span>Master Output</span>
</div>
<motion.span
key={value}
initial={{ scale: 0.8, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ duration: 0.15 }}
className="font-mono text-primary font-bold px-2 py-0.5 rounded-md bg-primary/10"
>
{value} dB
</motion.span>
</div>
<div
className="relative py-2"
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
<input
type="range"
min="0"
max="100"
value={value}
onChange={(e) => setValue(Number(e.target.value))}
className="w-full h-2.5 rounded-full appearance-none cursor-pointer bg-muted accent-primary focus:outline-none"
/>
{/* Floating spring badge */}
<motion.div
animate={{
scale: isHovered ? 1.05 : 1,
boxShadow: isHovered
? "0 10px 25px -5px rgba(99, 102, 241, 0.4)"
: "0 2px 5px rgba(0,0,0,0.1)",
}}
transition={{ type: "spring", stiffness: 400, damping: 25 }}
className="pointer-events-none mt-2 flex justify-between text-[10px] text-muted-foreground font-mono"
>
<span>Mute</span>
<span>Nominal</span>
<span>Peak</span>
</motion.div>
</div>
</div>
);
}