diff --git a/src/components/shared/FormField.tsx b/src/components/shared/FormField.tsx index 277f844..5213739 100644 --- a/src/components/shared/FormField.tsx +++ b/src/components/shared/FormField.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useState, type ReactNode } from 'react'; import type { ReactElement, InputHTMLAttributes } from 'react'; import { Eye, EyeOff } from 'lucide-react'; import { cn } from '@/lib/utils'; @@ -7,7 +7,7 @@ interface FormFieldProps extends InputHTMLAttributes { label: string; required?: boolean; error?: string; - helperText?: string; + helperText?: ReactNode; } export const FormField = ({ diff --git a/src/components/shared/FormSlider.tsx b/src/components/shared/FormSlider.tsx new file mode 100644 index 0000000..cc3d464 --- /dev/null +++ b/src/components/shared/FormSlider.tsx @@ -0,0 +1,102 @@ +import React from 'react'; +import { cn } from '@/lib/utils'; + +interface FormSliderProps { + label: string; + min: number; + max: number; + step?: number; + value: number; + onChange: (value: number) => void; + helperText?: string; + error?: string; + className?: string; +} + +export const FormSlider: React.FC = ({ + label, + min, + max, + step = 0.1, + value, + onChange, + helperText, + error, + className, +}) => { + // Calculate percentage for gradient track + const percentage = ((value - min) / (max - min)) * 100; + + return ( +
+
+ +
+ {value} +
+
+ +
+ onChange(parseFloat(e.target.value))} + className="form-range-slider w-full cursor-pointer appearance-none bg-transparent" + style={{ + background: `linear-gradient(to right, #00cfd5 0%, #00cfd5 ${percentage}%, #eff6ff ${percentage}%, #eff6ff 100%)`, + height: '4px', + borderRadius: '4px', + }} + /> +
+ {min} + {max} +
+
+ + {helperText && !error && ( +

+ {helperText} +

+ )} + {error && ( +

+ {error} +

+ )} + +