112 lines
3.0 KiB
TypeScript
112 lines
3.0 KiB
TypeScript
"use client";
|
|
|
|
import { FloatingLabelInputProps } from '#/types';
|
|
import React, { useState } from 'react';
|
|
import Image from 'next/image';
|
|
import { icons } from '#/assets/icons';
|
|
|
|
export default function FloatingLabelInput({
|
|
label,
|
|
placeholder,
|
|
type,
|
|
options,
|
|
button,
|
|
showPasswordToggle = false,
|
|
name,
|
|
defaultValue,
|
|
onChange
|
|
}: FloatingLabelInputProps) {
|
|
const [showPassword, setShowPassword] = useState(false);
|
|
|
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
|
|
const value = e.target.value;
|
|
if (onChange) {
|
|
onChange(value);
|
|
}
|
|
};
|
|
|
|
|
|
const renderInput = () => {
|
|
switch(type) {
|
|
case 'select':
|
|
return (
|
|
<div className="relative w-full">
|
|
<select
|
|
className="input-form focus:ring-2 focus:ring-blue-500 outline-none"
|
|
name={name}
|
|
defaultValue={defaultValue}
|
|
>
|
|
{options?.map((option, index) => (
|
|
<option key={index} value={option}>{option}</option>
|
|
))}
|
|
</select>
|
|
{button && <div className="btn-floating">{button}</div>}
|
|
</div>
|
|
);
|
|
|
|
case 'password':
|
|
return (
|
|
<div className="relative w-full">
|
|
<input
|
|
name={name}
|
|
type={showPassword ? "text" : "password"}
|
|
placeholder={placeholder}
|
|
className="input-form focus:ring-2 focus:ring-blue-500 pr-10 outline-none"
|
|
defaultValue={defaultValue}
|
|
|
|
/>
|
|
{showPasswordToggle && (
|
|
<button
|
|
type="button"
|
|
onClick={() => setShowPassword(!showPassword)}
|
|
className="btn-floating text-gray-500 hover:text-gray-700 focus:outline-none"
|
|
>
|
|
{showPassword ? (
|
|
<Image
|
|
src={icons.eyeSlashIcon}
|
|
width={20}
|
|
height={20}
|
|
alt=''
|
|
/>
|
|
) : (
|
|
<Image
|
|
src={icons.eyeIcon}
|
|
width={20}
|
|
height={20}
|
|
alt=''
|
|
/>
|
|
)}
|
|
</button>
|
|
)}
|
|
</div>
|
|
);
|
|
|
|
default:
|
|
return (
|
|
<div className="relative w-full">
|
|
<input
|
|
type={type}
|
|
placeholder={placeholder}
|
|
className="input-form focus:ring-2 focus:ring-blue-500 outline-none"
|
|
name={name}
|
|
defaultValue={defaultValue}
|
|
onChange={handleChange}
|
|
/>
|
|
{button && <div className="absolute right-0 top-1/2 transform -translate-y-1/2">{button}</div>}
|
|
</div>
|
|
);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="relative">
|
|
<label
|
|
htmlFor={name}
|
|
className="input-label text-gray-400 text-sm"
|
|
>
|
|
{label}
|
|
</label>
|
|
{renderInput()}
|
|
</div>
|
|
);
|
|
} |