KitlenoKitlenov2.0.0

Forms & Input / Form

Form

Form components are used to collect and manage user input in a structured way. They typically include inputs, labels, validation states, and submission controls, and are commonly used for tasks such as signing up, logging in, or updating user information.

Sign Up Form

A minimal sign up form with email validation and clear error feedback.

Create account

Join and get access to your dashboard.

Already have an account?
SignUpForm.jsx
'use client'
import { useState } from 'react'

export default function SignUpForm() {
  const [email, setEmail] = useState('')
  const [emailError, setEmailError] = useState('')

  const validateEmail = (value) => {
    return /^[^s@]+@[^s@]+.[^s@]+$/.test(value)
  }

  const handleSubmit = (e) => {
    e.preventDefault()

    if (!validateEmail(email)) {
      setEmailError('Please enter a valid email address.')
      return
    }

    setEmailError('')
  }

  const handleEmailChange = (value) => {
    setEmail(value)

    if (!value) {
      setEmailError('')
      return
    }

    if (!validateEmail(value)) {
      setEmailError('Please enter a valid email address.')
    } else {
      setEmailError('')
    }
  }

  return (
    <div className="w-full max-w-md">
      <form
        onSubmit={handleSubmit}
        className="rounded-3xl backdrop-blur-xl bg-white/80 dark:bg-[#1e1e1e] border dark:border-[#4c4c4c] border-zinc-200 p-8">
        <div className="mb-8">
          <h2 className="text-2xl font-semibold tracking-tight text-zinc-900 dark:text-[#f1f1f1]">Create account</h2>
          <p className="mt-2 text-sm text-zinc-500">Join and get access to your dashboard.</p>
        </div>

        <div className="space-y-5">
          <div>
            <label htmlFor="email" className="mb-2 block text-sm font-medium text-zinc-700 dark:text-[#f1f1f1]">
              Email
            </label>

            <input
              id="email"
              type="email"
              autoComplete="email"
              value={email}
              onChange={(e) => handleEmailChange(e.target.value)}
              placeholder="name@example.com"
              className={`w-full rounded-2xl border bg-white dark:bg-[#151515] dark:border-[#4a4a4a] px-4 py-3 text-sm outline-none transition-all
              ${emailError ? 'focus:border-[#e57373] border-[#e57373]' : 'border-zinc-200 focus:border-zinc-900'}`}/>
              {emailError && <p className="mt-2 text-sm text-[#e57373]">{emailError}</p>}
          </div>

          <button
            type="submit"
            className="cursor-pointer w-full rounded-2xl bg-zinc-900 px-4 py-3 text-sm font-medium text-white dark:bg-[#e6e6e6] dark:border dark:border-[#5a5a5a] dark:text-[#111111] dark:hover:bg-[#ffffff] dark:hover:border-[#777777] active:scale-[0.99]">
            Create account
          </button>
        </div>

        <div className="mt-6 text-center text-sm text-zinc-500">
          Already have an account?{' '}
          <button type="button" className="cursor-pointer font-medium text-zinc-900 dark:text-[#f1f1f1] hover:underline">
            Sign in
          </button>
        </div>
      </form>
    </div>
  )
}

Log In Form

A log in form with email and password validation, plus social login options for Google and Apple.

Welcome back

Login to continue to your dashboard.

or
Don't have an account?
LogInForm.jsx
'use client'
import { useState } from 'react'

export default function LogInForm() {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const [emailError, setEmailError] = useState('')
  const [passwordError, setPasswordError] = useState('')

  const validateEmail = (value) => {
    return /^[^s@]+@[^s@]+.[^s@]+$/.test(value)
  }

  const validatePassword = (value) => {
    return value.length >= 6
  }

  const handleEmailChange = (value) => {
    setEmail(value)

    if (!value) {
      setEmailError('')
      return
    }

    if (!validateEmail(value)) {
      setEmailError('Please enter a valid email address.')
    } else {
      setEmailError('')
    }
  }

  const handlePasswordChange = (value) => {
    setPassword(value)

    if (!value) {
      setPasswordError('')
      return
    }

    if (!validatePassword(value)) {
      setPasswordError('Password must be at least 6 characters.')
    } else {
      setPasswordError('')
    }
  }

  const handleSubmit = (e) => {
    e.preventDefault()

    let hasError = false

    if (!validateEmail(email)) {
      setEmailError('Please enter a valid email address.')
      hasError = true
    }

    if (!validatePassword(password)) {
      setPasswordError('Password must be at least 6 characters.')
      hasError = true
    }

    if (hasError) return
    setEmailError('')
    setPasswordError('')
  }

  return (
    <div className="w-full max-w-md">
      <form
        onSubmit={handleSubmit}
        className="rounded-3xl backdrop-blur-xl bg-white/80 dark:bg-[#1e1e1e] border dark:border-[#4c4c4c] border-zinc-200 p-8">
        <div className="mb-8">
          <h2 className="text-2xl font-semibold tracking-tight text-zinc-900 dark:text-[#f1f1f1]">Welcome back</h2>
          <p className="mt-2 text-sm text-zinc-500">Login to continue to your dashboard.</p>
        </div>

        <div className="space-y-3 mb-6">
          <button
            type="button"
            className="w-full flex items-center justify-center gap-2 rounded-2xl border border-zinc-200 dark:border-[#4a4a4a] bg-white dark:bg-[#151515] px-4 py-3 text-sm font-medium hover:bg-zinc-50 dark:hover:bg-[#202020] transition cursor-pointer">
            <img src="/icons/google.svg" alt="Google" className="h-5 w-5 shrink-0" />
            <span className="leading-none">Continue with Google</span>
          </button>

          <button
            type="button"
            className="w-full flex items-center justify-center gap-2 rounded-2xl border border-zinc-200 dark:border-[#4a4a4a] bg-white dark:bg-[#151515] px-4 py-3 text-sm font-medium hover:bg-zinc-50 dark:hover:bg-[#202020] transition cursor-pointer">
            <img src="/icons/apple.svg" alt="Apple" className="h-5 w-5 shrink-0 dark:hidden" />
            <img src="/icons/apple-white.svg" alt="Apple" className="h-5 w-5 shrink-0 hidden dark:block" />
            <span className="leading-none">Continue with Apple</span>
          </button>
        </div>

        <div className="flex items-center gap-3 mb-6">
          <div className="h-px flex-1 bg-zinc-200 dark:bg-[#333]" />
          <span className="text-xs text-zinc-400">or</span>
          <div className="h-px flex-1 bg-zinc-200 dark:bg-[#333]" />
        </div>

        <div className="space-y-5">
          <div>
            <label className="mb-2 block text-sm font-medium text-zinc-700 dark:text-[#f1f1f1]">Email</label>
            <input
              type="email"
              value={email}
              autoComplete="email"
              onChange={(e) => handleEmailChange(e.target.value)}
              placeholder="name@example.com"
              className={`w-full rounded-2xl border bg-white dark:bg-[#151515] dark:border-[#4a4a4a] px-4 py-3 text-sm outline-none transition-all
                ${emailError ? 'border-[#e57373] focus:border-[#e57373]' : 'border-zinc-200 focus:border-zinc-900'}`}/>
              {emailError && <p className="mt-2 text-sm text-[#e57373]">{emailError}</p>}
          </div>

          <div>
            <label className="mb-2 block text-sm font-medium text-zinc-700 dark:text-[#f1f1f1]">Password</label>
            <input
              type="password"
              value={password}
              autoComplete="current-password"
              onChange={(e) => handlePasswordChange(e.target.value)}
              placeholder="••••••••"
              className={`w-full rounded-2xl border bg-white dark:bg-[#151515] dark:border-[#4a4a4a] px-4 py-3 text-sm outline-none transition-all
                ${passwordError ? 'border-[#e57373] focus:border-[#e57373]' : 'border-zinc-200 focus:border-zinc-900'}`}/>
              {passwordError && <p className="mt-2 text-sm text-[#e57373]">{passwordError}</p>}
          </div>

          <button
            type="submit"
            className="w-full rounded-2xl bg-zinc-900 px-4 py-3 text-sm font-medium text-white dark:bg-[#e6e6e6] dark:text-[#111] dark:hover:bg-white active:scale-[0.99] transition cursor-pointer">
            Sign in
          </button>
        </div>

        <div className="mt-6 text-center text-sm text-zinc-500">
          Don’t have an account?{' '}
          <button type="button" className="font-medium text-zinc-900 dark:text-[#f1f1f1] hover:underline cursor-pointer">
            Create account
          </button>
        </div>
      </form>
    </div>
  )
}