46 lines
1.4 KiB
TypeScript
46 lines
1.4 KiB
TypeScript
import React from 'react';
|
|
|
|
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
icon?: React.ReactNode;
|
|
label?: string;
|
|
error?: string;
|
|
containerClassName?: string;
|
|
}
|
|
|
|
export default function Input({ icon, label, error, containerClassName = '', className = '', ...props }: InputProps) {
|
|
const innerId = React.useId();
|
|
const id = props.id || innerId;
|
|
|
|
return (
|
|
<div className={`space-y-1.5 ${containerClassName}`}>
|
|
{label && (
|
|
<label htmlFor={id} className="text-xs font-semibold text-slate-400 uppercase tracking-wider ml-1">
|
|
{label}
|
|
</label>
|
|
)}
|
|
<div className="relative">
|
|
{icon && (
|
|
<div className="absolute left-4 top-1/2 -translate-y-1/2 text-slate-500">
|
|
{icon}
|
|
</div>
|
|
)}
|
|
<input
|
|
id={id}
|
|
name={props.name || id}
|
|
className={`
|
|
w-full bg-black/30 border rounded-xl py-3 px-4 text-white
|
|
placeholder:text-slate-600
|
|
focus:outline-none focus:ring-2 focus:ring-brand-500/40 focus:border-brand-500/50
|
|
transition-all duration-200
|
|
${icon ? 'pl-12' : ''}
|
|
${error ? 'border-red-500/50' : 'border-white/10'}
|
|
${className}
|
|
`}
|
|
{...props}
|
|
/>
|
|
</div>
|
|
{error && <p className="text-xs text-red-400 ml-1">{error}</p>}
|
|
</div>
|
|
);
|
|
}
|