Components
Label

Label

Renders an accessible label associated with controls.

How it works

Install the following dependencies:

pnpm add motion

Create a new file at lib/utils.ts and add the provided code.

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

Create a file at components/ui/label.tsx and paste the given code.

label.tsx

"use client";
 
import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority";
import { HTMLMotionProps, motion } from "motion/react";
import { cn } from "@/lib/utils";
 
// Define variants for the Label component
const labelVariants = cva(
    "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
    {
        variants: {
            variant: {
                normal: "",
                float: "origin-start font-normal absolute top-0 block translate-y-2 cursor-text px-1 text-sm text-muted-foreground/70 transition-all group-focus-within:pointer-events-none group-focus-within:-translate-y-1/2 group-focus-within:cursor-default group-focus-within:text-xs group-focus-within:font-medium group-focus-within:text-foreground has-[+textarea:not(:placeholder-shown)]:pointer-events-none has-[+textarea:not(:placeholder-shown)]:-translate-y-1/2 has-[+textarea:not(:placeholder-shown)]:cursor-default has-[+textarea:not(:placeholder-shown)]:text-xs has-[+textarea:not(:placeholder-shown)]:font-medium has-[+textarea:not(:placeholder-shown)]:text-foreground",
            },
        },
        defaultVariants: {
            variant: "normal",
        },
    },
);
 
const _Label = React.forwardRef<
    HTMLLabelElement,
    HTMLMotionProps<"label"> & VariantProps<typeof labelVariants>
>(({ className, variant, ...props }, ref) => {
    return (
        <motion.label
            ref={ref}
            className={cn(labelVariants({ variant, className }))}
            {...props}
        />
    );
});
 
_Label.displayName = "Label";
 
// Optional: create motion-enhanced Label component (if you're using `motion` for animations)
const Label = motion.create(_Label);
 
export { Label };

Import and use the Accordion component in your application.

import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
 
import React from "react";
 
const LabelDemo = () => {
    return (
        <div className="w-full max-w-xs space-y-2">
            <Label htmlFor="email">Email</Label>
            <Input id="email" placeholder="Email" type="email" />
        </div>
    );
};
 
export default LabelDemo;