React + MotionInputs

Input con label flotante

La etiqueta vive dentro del campo y sube hasta el borde en cuanto haces clic o empiezas a escribir.

Ajustes

48px

Código

import { useState } from "react";
import { motion } from "framer-motion";

interface FloatingLabelInputProps {
  color?: string;
  size?: number;
  label?: string;
  type?: string;
  value?: string;
  defaultValue?: string;
  onChange?: (value: string) => void;
}

export default function FloatingLabelInput({
  color = "#0071e3",
  size = 48,
  label = "Correo electrónico",
  type = "text",
  value,
  defaultValue = "",
  onChange,
}: FloatingLabelInputProps) {
  const [internal, setInternal] = useState(defaultValue);
  const [focused, setFocused] = useState(false);
  const current = value ?? internal;
  const up = focused || current.length > 0;

  return (
    <div className="relative w-64">
      <input
        type={type}
        aria-label={label}
        value={current}
        onChange={(e) => {
          if (value === undefined) setInternal(e.target.value);
          onChange?.(e.target.value);
        }}
        onFocus={() => setFocused(true)}
        onBlur={() => setFocused(false)}
        className="w-full rounded-[14px] border bg-white px-3 outline-none transition-colors dark:bg-[#1c1c1e]"
        style={{
          height: size,
          fontSize: size / 3.2,
          borderColor: focused ? color : "oklch(1 0 0 / 14%)",
          boxShadow: focused ? `0 0 0 3px ${color}22` : "none",
        }}
      />
      <motion.label
        className={`pointer-events-none absolute left-3 px-1 ${up ? "bg-white dark:bg-[#1c1c1e]" : "bg-transparent"}`}
        animate={{
          top: up ? -8 : size / 2 - size / 6.4,
          fontSize: up ? 11 : size / 3.2,
          color: up ? color : "oklch(0.62 0.015 260)",
        }}
        transition={{ duration: 0.16 }}
      >
        {label}
      </motion.label>
    </div>
  );
}

Prompt para IA

Pégalo en ChatGPT, Claude o Cursor y adaptará el bloque a tu proyecto con estos ajustes, aunque no uses React.

Más en Inputs

Dónde usarlo

Las etiquetas flotantes ahorran espacio sin perder contexto: la pista sigue ahí después de escribir, algo que un placeholder no hace. Quedan bien en un registro o login, en el checkout de una tienda online o en la reserva de cita de una clínica. Un input con label flotante es un detalle pequeño que hace que el formulario parezca terminado.

Usa etiquetas cortas para que quepan al encogerse: «Email» mejor que «Tu dirección de correo». Ajusta la altura para que coincida con tus botones y elige un color de foco que destaque sobre el borde, así siempre se sabe dónde se está escribiendo.