FloatingLabel
floatinglabel-1779394643416.tsx
'use client'
import { useState } from 'react'
function FloatingInput({ label, type = 'text', validate }) {
const [value, setValue] = useState('')
const [focused, setFocused] = useState(false)
const [touched, setTouched] = useState(false)
const error = touched && validate ? validate(value) : null
const floated = focused || value.length > 0
return (
<div style={{ position:'relative', marginBottom:'8px' }}>
<input
type={type} value={value}
onChange={e=>setValue(e.target.value)}
onFocus={()=>setFocused(true)}
onBlur={()=>{setFocused(false);setTouched(true)}}
style={{
width:'100%', padding:'22px 14px 8px', fontSize:'15px', outline:'none',
border:'2px solid '+(error?'#ef4444':focused?'#6d28d9':'#e2e8f0'),
borderRadius:'10px', boxSizing:'border-box',
background:error?'#fff5f5':'#fff',
transition:'border-color 0.2s',
}}
/>
<label style={{
position:'absolute', left:'14px',
top:floated?'6px':'50%', transform:floated?'none':'translateY(-50%)',
fontSize:floated?'11px':'15px', color:error?'#ef4444':focused?'#6d28d9':'#94a3b8',
fontWeight:floated?700:400, transition:'all 0.2s', pointerEvents:'none',
textTransform:floated?'uppercase':none, letterSpacing:floated?'0.05em':'0',
}}>{label}</label>
{error && <div style={{ fontSize:'11px', color:'#ef4444', marginTop:'4px', marginLeft:'14px' }}>{error}</div>}
</div>
)
}
export default function FloatingLabelForm() {
return (
<div style={{ maxWidth:'360px', display:'flex', flexDirection:'column', gap:'4px' }}>
<FloatingInput label="Full Name" validate={v=>v.length<2?'Name too short':null}/>
<FloatingInput label="Email Address" type="email" validate={v=>!v.includes('@')?'Invalid email':null}/>
<FloatingInput label="Password" type="password" validate={v=>v.length<8?'Min 8 characters':null}/>
</div>
)
}Component info
CategoryInputs & Forms
Frameworkreact
TierFREE
Views0
Copies0
About
Input with floating label animation and validation states
More from Inputs & Forms
'use client';
import { useState, useEffect } from 'react';
interface Tag {
id: number;
name: string;
}
const TagInput = () => {
const [tags, setTags] = useState<Tag[]>([]);
const [inputValue, setInputValue] = useState('');
const [suggestTagInput
Inputs & Forms
'use client';
import React, { useState } from 'react';
interface File {
name: string;
size: number;
progress: number;
}
const FileUpload = () => {
const [dragOver, setDragOver] = useState(false);
const [files, setFiles] = useState<File[]FileUpload
Inputs & Forms
import React, { useState } from 'react';
const OTPInput = () => {
const [otp, setOtp] = useState(new Array(6).fill(''));
const [activeIndex, setActiveIndex] = useState(0);
const handleChange = (e, index) => {
const value = e.target.value;OTPInput
Inputs & Forms
'use client';
import React, { useState } from 'react';
interface RangeSliderProps {
min: number;
max: number;
defaultValue: [number, number];
}
const RangeSlider: React.FC<RangeSliderProps> = ({ min, max, defaultValue }) => {
const [minValRangeSlider
Inputs & Forms