ManimCat / frontend /src /components /settings-modal /FloatingInput.tsx
Bin29's picture
Sync from main: 68df783 feat: support multimodal studio reference images
d47b053
interface FloatingInputProps {
id: string;
label: string;
type: 'text' | 'password';
value: string;
placeholder: string;
onChange: (value: string) => void;
suggestions?: string[];
containerClassName?: string;
labelClassName?: string;
inputClassName?: string;
}
export function FloatingInput({
id,
label,
type,
value,
placeholder,
onChange,
suggestions,
containerClassName = '',
labelClassName = '',
inputClassName = '',
}: FloatingInputProps) {
const datalistId = suggestions && suggestions.length > 0 ? `${id}__datalist` : undefined;
return (
<div className={`relative ${containerClassName}`.trim()}>
<label
htmlFor={id}
className={`absolute left-4 -top-2.5 px-2 bg-bg-secondary text-xs font-medium text-text-secondary transition-all ${labelClassName}`.trim()}
>
{label}
</label>
<input
id={id}
type={type}
value={value}
list={datalistId}
onChange={(e) => onChange(e.target.value)}
placeholder={placeholder}
className={`w-full px-4 py-4 bg-bg-secondary/50 rounded-2xl text-sm text-text-primary placeholder-text-secondary/40 focus:outline-none focus:ring-2 focus:ring-accent/20 focus:bg-bg-secondary/70 transition-all ${inputClassName}`.trim()}
/>
{datalistId ? (
<datalist id={datalistId}>
{suggestions!.map((item) => (
<option key={item} value={item} />
))}
</datalist>
) : null}
</div>
);
}