112 lines
2.7 KiB
TypeScript
112 lines
2.7 KiB
TypeScript
/**
|
|
* FormFieldCompact Component
|
|
*
|
|
* Compact form field with label for constructor and settings editors.
|
|
* Supports text, number, textarea, and color input types.
|
|
*/
|
|
|
|
import React from 'react';
|
|
|
|
type FieldType = 'text' | 'number' | 'textarea' | 'color' | 'checkbox';
|
|
|
|
interface FormFieldCompactProps {
|
|
label: string;
|
|
value: string | number | boolean;
|
|
type?: FieldType;
|
|
placeholder?: string;
|
|
hint?: string;
|
|
min?: number;
|
|
max?: number;
|
|
step?: number;
|
|
rows?: number;
|
|
disabled?: boolean;
|
|
onChange: (value: string | boolean) => void;
|
|
}
|
|
|
|
const FormFieldCompact: React.FC<FormFieldCompactProps> = ({
|
|
label,
|
|
value,
|
|
type = 'text',
|
|
placeholder,
|
|
hint,
|
|
min,
|
|
max,
|
|
step,
|
|
rows = 4,
|
|
disabled = false,
|
|
onChange,
|
|
}) => {
|
|
if (type === 'checkbox') {
|
|
return (
|
|
<label className='flex items-center gap-2 text-[11px] text-gray-700'>
|
|
<input
|
|
type='checkbox'
|
|
checked={Boolean(value)}
|
|
disabled={disabled}
|
|
onChange={(event) => onChange(event.target.checked)}
|
|
/>
|
|
{label}
|
|
</label>
|
|
);
|
|
}
|
|
|
|
if (type === 'color') {
|
|
return (
|
|
<div>
|
|
<label className='mb-1 block text-[11px] font-semibold text-gray-600'>
|
|
{label}
|
|
</label>
|
|
<input
|
|
type='color'
|
|
className='w-full h-8 rounded border border-gray-300 px-1 py-1'
|
|
value={String(value || '#000000')}
|
|
disabled={disabled}
|
|
onChange={(event) => onChange(event.target.value)}
|
|
/>
|
|
{hint && <p className='mt-1 text-[11px] text-gray-500'>{hint}</p>}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (type === 'textarea') {
|
|
return (
|
|
<div>
|
|
<label className='mb-1 block text-[11px] font-semibold text-gray-600'>
|
|
{label}
|
|
</label>
|
|
<textarea
|
|
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
|
|
rows={rows}
|
|
value={String(value || '')}
|
|
placeholder={placeholder}
|
|
disabled={disabled}
|
|
onChange={(event) => onChange(event.target.value)}
|
|
/>
|
|
{hint && <p className='mt-1 text-[11px] text-gray-500'>{hint}</p>}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<label className='mb-1 block text-[11px] font-semibold text-gray-600'>
|
|
{label}
|
|
</label>
|
|
<input
|
|
type={type}
|
|
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
|
|
value={String(value ?? '')}
|
|
placeholder={placeholder}
|
|
min={min}
|
|
max={max}
|
|
step={step}
|
|
disabled={disabled}
|
|
onChange={(event) => onChange(event.target.value)}
|
|
/>
|
|
{hint && <p className='mt-1 text-[11px] text-gray-500'>{hint}</p>}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default FormFieldCompact;
|