Introducing Aceternity UI Pro - Premium component packs and templates to build awesome websites.
Logo

Signup Form

A customizable form built on top of shadcn's input and label, with a touch of framer motion

Open in

Welcome to Aceternity

Login to aceternity if you can because we don't have a login flow yet

Installation

Install dependencies

npm i motion clsx tailwind-merge @radix-ui/react-label @tabler/icons-react

Add util file

lib/utils.ts
import { ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
 
export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

Modify the config file to add a box shadow

app/globals.css
@import "tailwindcss";
 
@theme inline {
  --shadow-input:
    0px 2px 3px -1px rgba(0, 0, 0, 0.1),
    0px 1px 0px 0px rgba(25, 28, 33, 0.02),
    0px 0px 0px 1px rgba(25, 28, 33, 0.08);
}

Copy the source code

components/ui/input.tsx

// Input component extends from shadcnui - https://ui.shadcn.com/docs/components/input
"use client";
import * as React from "react";
import { cn } from "@/lib/utils";
import { useMotionTemplate, useMotionValue, motion } from "motion/react";
 
export interface InputProps
  extends React.InputHTMLAttributes<HTMLInputElement> {}
 
const Input = React.forwardRef<HTMLInputElement, InputProps>(
  ({ className, type, ...props }, ref) => {
    const radius = 100; // change this to increase the rdaius of the hover effect
    const [visible, setVisible] = React.useState(false);
 
    let mouseX = useMotionValue(0);
    let mouseY = useMotionValue(0);
 
    function handleMouseMove({ currentTarget, clientX, clientY }: any) {
      let { left, top } = currentTarget.getBoundingClientRect();
 
      mouseX.set(clientX - left);
      mouseY.set(clientY - top);
    }
    return (
      <motion.div
        style={{
          background: useMotionTemplate`
        radial-gradient(
          ${visible ? radius + "px" : "0px"} circle at ${mouseX}px ${mouseY}px,
          #3b82f6,
          transparent 80%
        )
      `,
        }}
        onMouseMove={handleMouseMove}
        onMouseEnter={() => setVisible(true)}
        onMouseLeave={() => setVisible(false)}
        className="group/input rounded-lg p-[2px] transition duration-300"
      >
        <input
          type={type}
          className={cn(
            `shadow-input dark:placeholder-text-neutral-600 flex h-10 w-full rounded-md border-none bg-gray-50 px-3 py-2 text-sm text-black transition duration-400 group-hover/input:shadow-none file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-neutral-400 focus-visible:ring-[2px] focus-visible:ring-neutral-400 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 dark:bg-zinc-800 dark:text-white dark:shadow-[0px_0px_1px_1px_#404040] dark:focus-visible:ring-neutral-600`,
            className,
          )}
          ref={ref}
          {...props}
        />
      </motion.div>
    );
  },
);
Input.displayName = "Input";
 
export { Input };

components/ui/label.tsx

// Label component extends from shadcnui - https://ui.shadcn.com/docs/components/label
 
"use client";
import * as React from "react";
import * as LabelPrimitive from "@radix-ui/react-label";
 
import { cn } from "@/lib/utils";
 
const Label = React.forwardRef<
  React.ElementRef<typeof LabelPrimitive.Root>,
  React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
>(({ className, ...props }, ref) => (
  <LabelPrimitive.Root
    ref={ref}
    className={cn(
      "text-sm font-medium text-black dark:text-white leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
      className
    )}
    {...props}
  />
));
Label.displayName = LabelPrimitive.Root.displayName;
 
export { Label };

Props

input.tsx

Prop NameTypeDescription
classNamestringAdditional CSS classes to apply to the input component.
typestringSpecifies the type of input (e.g., "text", "password"). Inherits all standard HTML input types.
...propsReact.InputHTMLAttributes<HTMLInputElement>Spreads the rest of the input attributes (e.g., placeholder, disabled, value, etc.) from React's InputHTMLAttributes.
refReact.Ref<HTMLInputElement>Ref forwarding is used to allow parent components to directly access the DOM input element.

label.tsx

PropTypeDescription
classNamestringAdditional CSS classes to apply to the label component.
...propsReact.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>All other props supported by LabelPrimitive.Root from @radix-ui/react-label.

Get beautiful, hand-crafted templates and components with Aceternity UI Pro

Professional, beautiful and elegant templates for your business. Get the best component packs and templates with Aceternity UI Pro.

Go Pro
I've been working with Manu for a couple of months now and I can't express enough how impressed I am with his talent. Manu's JavaScript/React web UI programming skills are through the roof. He's he...

Tony Pujals

Founder at Fantastic Realms, Tech Lead at Google

A product by Aceternity
Building in public at @mannupaaji