Search Components...

Floating Label Input

A textarea input that always shows the label and floats when the input has a value.

Loading...

Installation

npx shadcn@latest add /registry/floating-label-textarea.json

Manual Installation

Copy and paste the following code into your project.

import * as React from "react";
import { cn } from "@/lib/utils";
import { Textarea } from "@/components/ui/textarea";
import { FloatingLabel } from "./base/floating-label";
 
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
 
const FloatingTextArea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(({ className, ...props }, ref) => {
	return <Textarea placeholder=" " className={cn("peer bg-transparent border-none", className)} ref={ref} {...props} />;
});
FloatingTextArea.displayName = "FloatingTextArea";
 
export type FloatingLabelTextAreaProps = TextareaProps & {
	label: string;
	error?: boolean;
};
const FloatingLabelTextArea = React.forwardRef<React.ElementRef<typeof FloatingTextArea>, React.PropsWithoutRef<FloatingLabelTextAreaProps>>(
	({ id, label, error = false, className, ...props }, ref) => {
		return (
			<div className={cn("relative", error && "[&>*]:text-error [&>fieldset]:border-error [&>fieldset]:dark:border-error")}>
				<FloatingTextArea
					ref={ref}
					id={id}
					placeholder="  "
					className={cn(className, "focus-visible:ring-ring focus-visible:ring-0 focus-visible:ring-opacity-0 py-4")}
					{...props}
				/>
				<FloatingLabel
					htmlFor={id}
					className={cn("peer-focus:text-primary font-medium", {
						"text-error peer-focus:text-error": error,
					})}
					size="textarea">
					{label}
				</FloatingLabel>
				<fieldset
					className={cn(
						"absolute peer-focus-visible:border-2 transition-all peer-focus-visible:border-primary inset-0 -top-[5px] border dark:border-input/35 border-input/65 rounded-md m-0 py-0 text-left px-2 pointer-events-none min-w-0 peer-focus-visible:[&>legend]:max-w-full peer-placeholder-shown:[&>legend]:max-w-0",
					)}>
					<legend className="transition-all invisible whitespace-nowrap overflow-hidden w-auto max-w-full h-3 leading-4 text-xs font-normal p-0">
						<span className="px-1 visible inline-block opacity-0">{label}</span>
					</legend>
				</fieldset>
			</div>
		);
	},
);
 
FloatingLabelTextArea.displayName = "FloatingLabelTextArea";
 
export { FloatingLabelTextArea };

Base label for floating-label-textarea components.

import * as React from "react";
import { Label } from "@/components/ui/label";
import { cn } from "@/lib/utils";
import { cva, type VariantProps } from "class-variance-authority";
 
// ----------------------------------------------------------------------
 
const floatingLabelVariant = cva(
	"cursor-text text-muted-foreground absolute z-10 duration-300 peer-placeholder-shown:start-3 font-medium leading-4 text-xs peer-focus:text-xs start-3 peer-focus:start-3 -top-2 peer-focus:-top-2",
	{
		variants: {
			size: {
				sm: "peer-placeholder-shown:text-sm peer-placeholder-shown:top-3.5",
				md: "peer-placeholder-shown:text-base peer-placeholder-shown:top-3.5",
				lg: "peer-placeholder-shown:text-lg peer-placeholder-shown:top-4",
				textarea: "peer-placeholder-shown:text-base peer-placeholder-shown:top-3.5",
			},
		},
		defaultVariants: {
			size: "sm",
		},
	},
);
 
interface FloatingLabelProps extends React.ComponentPropsWithoutRef<typeof Label>, VariantProps<typeof floatingLabelVariant> {}
 
const FloatingLabel = React.forwardRef<React.ElementRef<typeof Label>, FloatingLabelProps>(({ size = "sm", className, ...props }, ref) => {
	return (
		<Label
			className={cn("select-none pointer-events-none transition-all", floatingLabelVariant({ size, className }))}
			ref={ref}
			{...props}
		/>
	);
});
FloatingLabel.displayName = "FloatingLabel";
 
export { FloatingLabel, floatingLabelVariant, type FloatingLabelProps };

Shadcn

This component is built on top of the excellent foundation provided by Shadcn/UI.

For a deeper dive into the core concepts and building blocks, check out the original Shadcn textarea component.