← Components/Forms

FloatingLabelInput

floatinglabelinput-1779378816967.tsx
'use client'
import { useState } from 'react'

interface FloatingLabelInputProps {
  label?: string
  type?: string
  maxLength?: number
  required?: boolean
  pattern?: string
  helperText?: string
}

export default function FloatingLabelInput({ label = 'Email address', type = 'email', maxLength = 60, required = true, helperText = 'We never share your email.' }: FloatingLabelInputProps) {
  const [value, setValue] = useState('')
  const [focused, setFocused] = useState(false)
  const [touched, setTouched] = useState(false)

  const isValid = type === 'email' ? /^[^s@]+@[^s@]+.[^s@]+$/.test(value) : value.length > 0
  const showError = touched && !isValid && value.length > 0
  const showSuccess = touched && isValid && value.length > 0

  const borderColor = showError ? '#ef4444' : showSuccess ? '#22c55e' : focused ? '#C9A84C' : 'rgba(255,255,255,0.12)'
  const labelColor = showError ? '#ef4444' : showSuccess ? '#22c55e' : focused ? '#C9A84C' : 'rgba(255,255,255,0.4)'

  return (
    <div style={{ padding: 40, background: '#0A0A0A', display: 'flex', flexDirection: 'column', gap: 24, alignItems: 'center', minHeight: 200, justifyContent: 'center' }}>
      {[
        { label: 'Email address', type: 'email', helper: 'We never share your email.' },
        { label: 'Password', type: 'password', helper: 'Minimum 8 characters.' },
        { label: 'Full name', type: 'text', helper: 'As it appears on your ID.' },
      ].map(field => {
        const [fval, setFval] = useState('')
        const [ffoc, setFfoc] = useState(false)
        const [ftouch, setFtouch] = useState(false)
        const fvalid = field.type === 'email' ? /^[^s@]+@[^s@]+.[^s@]+$/.test(fval) : fval.length >= (field.type === 'password' ? 8 : 1)
        const ferr = ftouch && !fvalid && fval.length > 0
        const fok = ftouch && fvalid
        const fborder = ferr ? '#ef4444' : fok ? '#22c55e' : ffoc ? '#C9A84C' : 'rgba(255,255,255,0.12)'
        const flabel = ferr ? '#ef4444' : fok ? '#22c55e' : ffoc ? '#C9A84C' : 'rgba(255,255,255,0.4)'
        const floated = ffoc || fval.length > 0

        return (
          <div key={field.label} style={{ position: 'relative', width: 320 }}>
            <label style={{
              position: 'absolute', left: 14, top: floated ? -10 : 16,
              fontSize: floated ? 11 : 14, color: flabel,
              background: floated ? '#0A0A0A' : 'transparent',
              padding: floated ? '0 4px' : 0,
              transition: 'all 0.2s', pointerEvents: 'none', zIndex: 1,
            }}>{field.label}{required && ' *'}</label>
            <input
              type={field.type === 'password' ? 'password' : 'text'}
              value={fval}
              onChange={e => setFval(e.target.value)}
              onFocus={() => setFfoc(true)}
              onBlur={() => { setFfoc(false); setFtouch(true) }}
              maxLength={maxLength}
              style={{
                width: '100%', boxSizing: 'border-box',
                background: 'rgba(255,255,255,0.03)', border: `1.5px solid ${fborder}`,
                borderRadius: 10, color: '#F5F5F0', fontSize: 14,
                padding: '16px 40px 8px 14px', outline: 'none',
                transition: 'border-color 0.2s',
              }}
            />
            {(fok || ferr) && (
              <span style={{ position: 'absolute', right: 12, top: 16, fontSize: 16 }}>
                {fok ? '✓' : '✗'}
              </span>
            )}
            <div style={{ marginTop: 4, fontSize: 11, color: ferr ? '#ef4444' : 'rgba(255,255,255,0.35)', paddingLeft: 4 }}>
              {ferr ? (field.type === 'email' ? 'Invalid email address' : field.type === 'password' ? 'Too short' : 'Required') : field.helper}
            </div>
          </div>
        )
      })}
    </div>
  )
}

Component info

CategoryForms
Frameworkreact
TierFREE
Views0
Copies0

About

Input with animated floating label, validation states, and character counter

More from Forms

'use client'
import { useState } from 'react'

const STEPS = [
  { title: 'Account', fields: ['name', 'email'] },
  { title: 'Profile', fields: ['role', 'company'] },
  { title: 'Confirm', fields: [] },
]

export default function MultiStepForm() {
  
MultiStepForm
Forms