70 lines
1.7 KiB
TypeScript
70 lines
1.7 KiB
TypeScript
import clsx from "clsx";
|
|
import { ComponentProps } from "react";
|
|
|
|
|
|
|
|
interface TextInputProps extends ComponentProps<"input">{
|
|
id: string;
|
|
inputClasses?: string;
|
|
labelClasses?: string;
|
|
accepted?: boolean;
|
|
}
|
|
|
|
|
|
export default function TextInput(inProps: TextInputProps){
|
|
const props = {...inProps};
|
|
const { id, placeholder, name, inputClasses, labelClasses, accepted } = props;
|
|
delete props.inputClasses;
|
|
delete props.labelClasses;
|
|
delete props.accepted;
|
|
|
|
|
|
return (
|
|
<div
|
|
className="flex flex-row justify-center w-full rounded-sm bg-inherit"
|
|
>
|
|
<div
|
|
className="relative bg-inherit w-full"
|
|
>
|
|
<input
|
|
{...props}
|
|
type="text"
|
|
className={clsx(
|
|
"peer bg-transparent w-full min-w-72 px-2 py-1 rounded-lg",
|
|
"ring-2 focus:ring-sky-600 placeholder-transparent outline-hidden",
|
|
inputClasses,
|
|
{
|
|
"ring-gray-500": accepted === undefined,
|
|
"ring-red-600": accepted === false,
|
|
"ring-green-600": accepted === true
|
|
}
|
|
)}
|
|
name={name}
|
|
/>
|
|
<label
|
|
htmlFor={id}
|
|
id={`${id}Label`}
|
|
className={clsx(
|
|
"absolute cursor-text left-0 -top-3 mx-1 px-1",
|
|
"bg-white dark:bg-neutral-825 text-sm",
|
|
"peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-500 peer-placeholder-shown:top-1 peer-focus:-top-3 peer-focus:text-sky-600 peer-focus:text-sm",
|
|
labelClasses,
|
|
{
|
|
"text-gray-500": accepted === undefined,
|
|
"text-red-600": accepted === false,
|
|
"text-green-600": accepted === true
|
|
}
|
|
)}
|
|
style={{
|
|
transitionProperty: "top, font-size, line-height",
|
|
transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
|
|
transitionDuration: "150ms"
|
|
}}
|
|
>
|
|
{placeholder}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|