import { forwardRef, type InputHTMLAttributes, type TextareaHTMLAttributes, } from "react"; interface InputProps extends InputHTMLAttributes { label?: string; error?: string; hint?: string; leftIcon?: React.ReactNode; rightIcon?: React.ReactNode; } export const Input = forwardRef( ( { label, error, hint, leftIcon, rightIcon, className = "", id, ...props }, ref, ) => { const inputId = id || label?.toLowerCase().replace(/\s+/g, "-"); const errorId = error ? `${inputId}-error` : undefined; const hintId = hint ? `${inputId}-hint` : undefined; const describedBy = [errorId, hintId].filter(Boolean).join(" ") || undefined; return (
{label && ( )}
{leftIcon && (
{leftIcon}
)} {rightIcon && (
{rightIcon}
)}
{error && ( )} {hint && !error && (

{hint}

)}
); }, ); Input.displayName = "Input"; interface TextareaProps extends TextareaHTMLAttributes { label?: string; error?: string; hint?: string; } export const Textarea = forwardRef( ({ label, error, hint, className = "", id, ...props }, ref) => { const textareaId = id || label?.toLowerCase().replace(/\s+/g, "-"); const errorId = error ? `${textareaId}-error` : undefined; const hintId = hint ? `${textareaId}-hint` : undefined; const describedBy = [errorId, hintId].filter(Boolean).join(" ") || undefined; return (
{label && ( )}