90 lines
2.8 KiB
TypeScript
90 lines
2.8 KiB
TypeScript
import React from 'react'
|
|
|
|
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
label?: string
|
|
error?: string
|
|
helperText?: string
|
|
}
|
|
|
|
export const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|
({ label, error, helperText, className = '', ...props }, ref) => {
|
|
return (
|
|
<div className="w-full">
|
|
{label && (
|
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
|
{label}
|
|
</label>
|
|
)}
|
|
<input
|
|
ref={ref}
|
|
className={`
|
|
w-full px-3 py-2 text-sm bg-white dark:bg-slate-900
|
|
border ${error ? 'border-red-500' : 'border-gray-200 dark:border-gray-800'}
|
|
rounded-md outline-none
|
|
focus:ring-2 ${error ? 'focus:ring-red-500' : 'focus:ring-indigo-500'}
|
|
focus:border-transparent
|
|
placeholder-gray-400 dark:placeholder-gray-600
|
|
text-gray-900 dark:text-white
|
|
disabled:opacity-60 disabled:cursor-not-allowed
|
|
duration-200
|
|
${className}
|
|
`}
|
|
{...props}
|
|
/>
|
|
{error && (
|
|
<p className="mt-1 text-sm text-red-500">{error}</p>
|
|
)}
|
|
{helperText && !error && (
|
|
<p className="mt-1 text-sm text-gray-500 dark:text-gray-400">{helperText}</p>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
)
|
|
|
|
Input.displayName = 'Input'
|
|
|
|
export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
label?: string
|
|
error?: string
|
|
helperText?: string
|
|
}
|
|
|
|
export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|
({ label, error, helperText, className = '', ...props }, ref) => {
|
|
return (
|
|
<div className="w-full">
|
|
{label && (
|
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
|
{label}
|
|
</label>
|
|
)}
|
|
<textarea
|
|
ref={ref}
|
|
className={`
|
|
w-full px-3 py-2 text-sm bg-white dark:bg-slate-900
|
|
border ${error ? 'border-red-500' : 'border-gray-200 dark:border-gray-800'}
|
|
rounded-md outline-none
|
|
focus:ring-2 ${error ? 'focus:ring-red-500' : 'focus:ring-indigo-500'}
|
|
focus:border-transparent
|
|
placeholder-gray-400 dark:placeholder-gray-600
|
|
text-gray-900 dark:text-white
|
|
disabled:opacity-60 disabled:cursor-not-allowed
|
|
duration-200
|
|
${className}
|
|
`}
|
|
{...props}
|
|
/>
|
|
{error && (
|
|
<p className="mt-1 text-sm text-red-500">{error}</p>
|
|
)}
|
|
{helperText && !error && (
|
|
<p className="mt-1 text-sm text-gray-500 dark:text-gray-400">{helperText}</p>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
)
|
|
|
|
Textarea.displayName = 'Textarea'
|