104 lines
2.8 KiB
TypeScript
104 lines
2.8 KiB
TypeScript
// components/FormField.tsx
|
|
// Переиспользуемые поля формы
|
|
|
|
import { ChangeEvent } from 'react';
|
|
import type { CalculatorField } from '@/types/calculator';
|
|
|
|
interface FormFieldProps {
|
|
field: CalculatorField;
|
|
value: string;
|
|
onChange: (value: string) => void;
|
|
}
|
|
|
|
export default function FormField({ field, value, onChange }: FormFieldProps) {
|
|
const id = `field-${field.id}`;
|
|
|
|
if (field.type === 'number') {
|
|
return (
|
|
<div className="relative mt-6">
|
|
<input
|
|
id={id}
|
|
type="number"
|
|
value={value}
|
|
onChange={(e) => onChange(e.target.value)}
|
|
placeholder=" "
|
|
className={`
|
|
peer
|
|
h-10 w-full
|
|
bg-gray-700
|
|
border-2 border-gray-600
|
|
rounded-md
|
|
text-gray-200
|
|
placeholder-transparent
|
|
pl-3
|
|
focus:outline-none focus:border-sky-500
|
|
appearance-none
|
|
`}
|
|
/>
|
|
<label
|
|
htmlFor={id}
|
|
className={`
|
|
absolute left-3
|
|
-top-5
|
|
text-gray-400
|
|
transition-all
|
|
text-xs sm:text-sm md:text-base lg:text-lg
|
|
peer-placeholder-shown:top-2
|
|
peer-placeholder-shown:text-gray-500
|
|
peer-placeholder-shown:text-sm sm:peer-placeholder-shown:text-base md:peer-placeholder-shown:text-lg
|
|
peer-focus:-top-5
|
|
peer-focus:text-gray-200
|
|
peer-focus:text-xs sm:peer-focus:text-sm md:peer-focus:text-base lg:peer-focus:text-lg
|
|
`}
|
|
>
|
|
{field.label} {field.required && '*'}
|
|
</label>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// text field
|
|
return (
|
|
<div className="relative mt-6">
|
|
<input
|
|
id={id}
|
|
type="text"
|
|
value={value}
|
|
onChange={(e) => onChange(e.target.value)}
|
|
placeholder=" "
|
|
className={`
|
|
peer
|
|
h-10 w-full
|
|
bg-gray-700
|
|
border-2 border-gray-600
|
|
rounded-md
|
|
text-gray-200
|
|
placeholder-transparent
|
|
pl-3
|
|
focus:outline-none focus:border-sky-500
|
|
appearance-none
|
|
`}
|
|
/>
|
|
<label
|
|
htmlFor={id}
|
|
className={`
|
|
absolute left-3
|
|
-top-5
|
|
text-gray-400
|
|
transition-all
|
|
text-xs sm:text-sm md:text-base lg:text-lg
|
|
peer-placeholder-shown:top-2
|
|
peer-placeholder-shown:text-gray-500
|
|
peer-placeholder-shown:text-sm sm:peer-placeholder-shown:text-base md:peer-placeholder-shown:text-lg
|
|
peer-focus:-top-5
|
|
peer-focus:text-gray-200
|
|
peer-focus:text-xs sm:peer-focus:text-sm md:peer-focus:text-base lg:peer-focus:text-lg
|
|
`}
|
|
>
|
|
{field.label} {field.required && '*'}
|
|
</label>
|
|
</div>
|
|
);
|
|
}
|
|
|