Files
chat_room/admin/src/components/ui/TextField.tsx
T
mobiniqow 75a0ba593d chore: merge admin repo history into monorepo at admin/
git-subtree-dir: admin
git-subtree-mainline: 35f5084005
git-subtree-split: 9f1eccd2f7
2026-09-27 10:30:47 +03:30

61 lines
2.1 KiB
TypeScript

"use client";
import { InputHTMLAttributes, forwardRef, useId } from "react";
import { cn } from "@/lib/utils";
interface TextFieldProps extends InputHTMLAttributes<HTMLInputElement> {
label?: string;
helperText?: string;
errorText?: string;
leadingIcon?: React.ReactNode;
}
export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
({ className, label, helperText, errorText, leadingIcon, id, ...props }, ref) => {
const autoId = useId();
const inputId = id ?? autoId;
const hasError = Boolean(errorText);
return (
<div className="flex flex-col gap-1.5 w-full">
{label && (
<label
htmlFor={inputId}
className="text-[13px] font-semibold text-(--color-content-secondary) px-1"
>
{label}
</label>
)}
<div className="relative">
{leadingIcon && (
<span className="absolute inset-y-0 right-4 flex items-center text-(--color-content-tertiary)">
{leadingIcon}
</span>
)}
<input
ref={ref}
id={inputId}
className={cn(
"h-12 w-full rounded-(--radius-sm) bg-(--color-surface-default)",
"border-2 border-(--color-border-default) px-4 text-[15px] text-(--color-content-primary)",
"placeholder:text-(--color-content-tertiary) transition-colors duration-150",
"focus:outline-none focus:border-(--color-border-interactive) focus:ring-4 focus:ring-(--color-brand-100)",
hasError &&
"border-(--color-status-error) focus:border-(--color-status-error) focus:ring-red-100",
leadingIcon && "pr-11",
className
)}
{...props}
/>
</div>
{errorText ? (
<p className="text-[12px] text-(--color-status-error) px-1">{errorText}</p>
) : helperText ? (
<p className="text-[12px] text-(--color-content-tertiary) px-1">{helperText}</p>
) : null}
</div>
);
}
);
TextField.displayName = "TextField";