50 lines
1.4 KiB
TypeScript
50 lines
1.4 KiB
TypeScript
import React from 'react'
|
|
|
|
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
label: string
|
|
id: string
|
|
error?: string
|
|
}
|
|
|
|
const Input: React.FC<InputProps> = ({
|
|
label,
|
|
id,
|
|
error,
|
|
className,
|
|
...props
|
|
}) => {
|
|
const baseClasses =
|
|
'mt-1 block w-full px-3 py-2 bg-white border border-slate-300 rounded-md text-sm shadow-sm placeholder-slate-400 focus:outline-none focus:border-sky-500 focus:ring-1 focus:ring-sky-500 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none'
|
|
const errorClasses =
|
|
'border-red-500 text-red-600 focus:border-red-500 focus:ring-red-500'
|
|
|
|
return (
|
|
<div className="mb-4">
|
|
<label
|
|
htmlFor={id}
|
|
className="block text-sm font-medium text-slate-700"
|
|
>
|
|
{label}
|
|
</label>
|
|
<input
|
|
id={id}
|
|
className={`${baseClasses} ${error ? errorClasses : ''} ${className || ''}`}
|
|
{...props}
|
|
aria-invalid={!!error}
|
|
aria-describedby={error ? `${id}-error` : undefined}
|
|
/>
|
|
{error && (
|
|
<p
|
|
id={`${id}-error`}
|
|
className="mt-1 text-xs text-red-600"
|
|
role="alert"
|
|
>
|
|
{error}
|
|
</p>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default Input
|