70 lines
2.1 KiB
TypeScript
70 lines
2.1 KiB
TypeScript
import * as React from "react";
|
|
import { LucideIcon } from "lucide-react";
|
|
import { cn } from "../../lib/utils";
|
|
|
|
interface InputProps extends React.ComponentProps<"input"> {
|
|
iconSrc?: string;
|
|
iconComponent?: LucideIcon | string;
|
|
iconProps?: {
|
|
size?: number;
|
|
color?: string;
|
|
strokeWidth?: number;
|
|
className?: string;
|
|
};
|
|
}
|
|
|
|
const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|
(
|
|
{
|
|
className,
|
|
type,
|
|
dir,
|
|
iconSrc,
|
|
iconComponent: IconComponent,
|
|
iconProps,
|
|
...props
|
|
},
|
|
ref
|
|
) => {
|
|
return (
|
|
<div className="relative w-full">
|
|
<input
|
|
type={type}
|
|
className={cn(
|
|
`flex h-[48px] w-full rounded-[12px] border border-input bg-inputBg dark:bg-gray-800 dark:border-gray-600 ${iconSrc || IconComponent ? (dir === "ltr" ? "pl-10 pr-3" : "pr-10 pl-3") : "px-3"} py-1 text-base text-foreground dark:text-gray-100 shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-inputPlaceholder dark:placeholder:text-gray-400 focus:outline-none focus:border-blue-300 dark:focus:border-blue-500 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm`,
|
|
className
|
|
)}
|
|
ref={ref}
|
|
{...props}
|
|
dir={dir}
|
|
/>
|
|
{(iconSrc || IconComponent) && (
|
|
<div
|
|
className={`absolute top-3.5 ${dir === "ltr" ? "left-2.5" : "right-2.5"}`}
|
|
>
|
|
{iconSrc ? (
|
|
<img
|
|
alt=""
|
|
src={iconSrc}
|
|
style={{ width: "24px", height: "24px" }}
|
|
/>
|
|
) : IconComponent ? (
|
|
<IconComponent
|
|
size={iconProps?.size || 20}
|
|
color={iconProps?.color}
|
|
strokeWidth={iconProps?.strokeWidth}
|
|
className={
|
|
iconProps?.className || "text-gray-500 dark:text-gray-400"
|
|
}
|
|
/>
|
|
) : null}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
);
|
|
Input.displayName = "Input";
|
|
|
|
export { Input };
|