one-day-update-vna
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
interface CustomSliderProps {
|
||||
label?: string;
|
||||
value: number;
|
||||
min?: number;
|
||||
max?: number;
|
||||
step?: number;
|
||||
|
||||
onChange?: (value: number) => void;
|
||||
|
||||
showValue?: boolean;
|
||||
disabled?: boolean;
|
||||
|
||||
className?: string;
|
||||
labelClassName?: string;
|
||||
sliderClassName?: string;
|
||||
thumbClassName?: string;
|
||||
trackClassName?: string;
|
||||
|
||||
color?: string;
|
||||
trackColor?: string;
|
||||
|
||||
renderValue?: (value: number) => React.ReactNode;
|
||||
}
|
||||
|
||||
const CustomSlider = ({
|
||||
label,
|
||||
value,
|
||||
min = 0,
|
||||
max = 1,
|
||||
step = 0.01,
|
||||
|
||||
onChange,
|
||||
|
||||
showValue = true,
|
||||
disabled = false,
|
||||
|
||||
className,
|
||||
labelClassName,
|
||||
sliderClassName,
|
||||
|
||||
color = "#2563eb",
|
||||
trackColor = "#e5e7eb",
|
||||
|
||||
renderValue,
|
||||
}: CustomSliderProps) => {
|
||||
const percentage = ((value - min) / (max - min)) * 100;
|
||||
|
||||
return (
|
||||
<div className={clsx("w-full space-y-3", className)}>
|
||||
{/* Header */}
|
||||
{(label || showValue) && (
|
||||
<div
|
||||
className={clsx("flex items-center justify-between", labelClassName)}
|
||||
>
|
||||
{label && (
|
||||
<span className="text-sm font-medium text-gray-700">{label}</span>
|
||||
)}
|
||||
|
||||
{showValue && (
|
||||
<span className="text-sm font-semibold text-gray-900">
|
||||
{renderValue ? renderValue(value) : value}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Slider */}
|
||||
<input
|
||||
type="range"
|
||||
min={min}
|
||||
max={max}
|
||||
step={step}
|
||||
disabled={disabled}
|
||||
value={value}
|
||||
onChange={(e) => onChange?.(Number(e.target.value))}
|
||||
className={clsx(
|
||||
`
|
||||
w-full
|
||||
appearance-none
|
||||
bg-transparent
|
||||
cursor-pointer
|
||||
|
||||
disabled:opacity-50
|
||||
disabled:cursor-not-allowed
|
||||
|
||||
[&::-webkit-slider-runnable-track]:h-2
|
||||
[&::-webkit-slider-runnable-track]:rounded-full
|
||||
|
||||
[&::-webkit-slider-thumb]:appearance-none
|
||||
[&::-webkit-slider-thumb]:h-6
|
||||
[&::-webkit-slider-thumb]:w-6
|
||||
[&::-webkit-slider-thumb]:rounded-full
|
||||
[&::-webkit-slider-thumb]:bg-white
|
||||
[&::-webkit-slider-thumb]:border-4
|
||||
[&::-webkit-slider-thumb]:shadow-md
|
||||
[&::-webkit-slider-thumb]:-mt-2
|
||||
|
||||
[&::-moz-range-track]:h-2
|
||||
[&::-moz-range-track]:rounded-full
|
||||
|
||||
[&::-moz-range-thumb]:h-6
|
||||
[&::-moz-range-thumb]:w-6
|
||||
[&::-moz-range-thumb]:rounded-full
|
||||
[&::-moz-range-thumb]:bg-white
|
||||
[&::-moz-range-thumb]:border-4
|
||||
`,
|
||||
sliderClassName,
|
||||
)}
|
||||
style={{
|
||||
background: `linear-gradient(to right, ${color} ${percentage}%, ${trackColor} ${percentage}%)`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomSlider;
|
||||
Reference in New Issue
Block a user