Files
family-planner/apps/client/src/components/ui/Input.tsx
T

39 lines
1.2 KiB
TypeScript
Raw Normal View History

import { forwardRef, InputHTMLAttributes } from 'react';
import { clsx } from 'clsx';
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
hint?: string;
}
export const Input = forwardRef<HTMLInputElement, InputProps>(
({ label, error, hint, className, id, ...props }, ref) => {
const inputId = id ?? label?.toLowerCase().replace(/\s+/g, '-');
return (
<div className="flex flex-col gap-1.5">
{label && (
<label htmlFor={inputId} className="text-sm font-medium text-secondary">
{label}
</label>
)}
<input
ref={ref}
id={inputId}
className={clsx(
'w-full rounded-lg border border-theme bg-surface-raised px-3 py-2 text-sm text-primary',
'placeholder:text-muted focus:outline-none focus:ring-2 ring-accent focus:border-transparent',
'transition-colors duration-150',
error && 'border-red-400 focus:ring-red-400',
className
)}
{...props}
/>
{hint && !error && <p className="text-xs text-muted">{hint}</p>}
{error && <p className="text-xs text-red-500">{error}</p>}
</div>
);
}
);
Input.displayName = 'Input';