Skip to Content
Prisma UI - React component library
ComponentsComponentsFloating Label Input

Floating Label Input

An input component with a label that floats above the field when focused or filled. Uses a compound component pattern (FloatingLabel, FloatingLabel.Input, FloatingLabel.Label) for full styling control. Inspired by shadcn/ui Expansions .

Installation

npx shadcn@latest add https://prismaui.com/components/floating-label-input.json

Import

import { FloatingLabel } from '@/components/ui/floating-label-input';

Preview

<FloatingLabel> <FloatingLabel.Input id='email' type='email' /> <FloatingLabel.Label htmlFor='email'>Email</FloatingLabel.Label> </FloatingLabel>

Multiple Fields

<div className='flex flex-col gap-4'> <FloatingLabel> <FloatingLabel.Input id='name' /> <FloatingLabel.Label htmlFor='name'>Full Name</FloatingLabel.Label> </FloatingLabel> <FloatingLabel> <FloatingLabel.Input id='email' type='email' /> <FloatingLabel.Label htmlFor='email'>Email</FloatingLabel.Label> </FloatingLabel> <FloatingLabel> <FloatingLabel.Input id='password' type='password' /> <FloatingLabel.Label htmlFor='password'>Password</FloatingLabel.Label> </FloatingLabel> </div>

Custom Styling

Each sub-component accepts its own className, giving full control without extra wrapper props.

<FloatingLabel> <FloatingLabel.Input id='username' className='rounded-full border-primary/50 px-5 focus:border-primary' /> <FloatingLabel.Label htmlFor='username' className='left-3 text-primary'> Username </FloatingLabel.Label> </FloatingLabel>

With Field (Description)

Wrap FloatingLabel inside a shadcn Field to add descriptions, errors, and accessible form layouts.

We’ll never share your email.

import { Field, FieldDescription } from '@/components/ui/field';
<Field> <FloatingLabel> <FloatingLabel.Input id='email' type='email' /> <FloatingLabel.Label htmlFor='email'>Email</FloatingLabel.Label> </FloatingLabel> <FieldDescription>We'll never share your email.</FieldDescription> </Field>

With Field (Error)

Use data-invalid on Field and aria-invalid on the input to show validation errors.

import { Field, FieldError } from '@/components/ui/field';
<Field data-invalid> <FloatingLabel> <FloatingLabel.Input id='email' type='email' aria-invalid /> <FloatingLabel.Label htmlFor='email'>Email</FloatingLabel.Label> </FloatingLabel> <FieldError>Enter a valid email address.</FieldError> </Field>

With Field (Validation)

A complete example with interactive validation — the error appears when the input loses focus and the value is too short.

Must be at least 3 characters.

'use client'; import { useState } from 'react'; import { FloatingLabel } from '@/components/ui/floating-label-input'; import { Field, FieldDescription, FieldError } from '@/components/ui/field'; export function FieldValidationDemo() { const [value, setValue] = useState(''); const [touched, setTouched] = useState(false); const isInvalid = touched && value.length < 3; return ( <Field data-invalid={isInvalid || undefined}> <FloatingLabel> <FloatingLabel.Input id='username' value={value} onChange={(e) => setValue(e.target.value)} onBlur={() => setTouched(true)} aria-invalid={isInvalid || undefined} /> <FloatingLabel.Label htmlFor='username'>Username</FloatingLabel.Label> </FloatingLabel> <FieldDescription>Must be at least 3 characters.</FieldDescription> {isInvalid && ( <FieldError>Username must be at least 3 characters.</FieldError> )} </Field> ); }

With FieldSet (Form)

Group multiple floating label inputs inside a FieldSet with FieldGroup for a complete form layout.

Account Information

Fill in your account details below.

We’ll send a confirmation to this address.

Must be at least 8 characters.

import { Field, FieldDescription, FieldGroup, FieldSet, FieldLegend, } from '@/components/ui/field';
<FieldSet> <FieldLegend>Account Information</FieldLegend> <FieldDescription>Fill in your account details below.</FieldDescription> <FieldGroup> <Field> <FloatingLabel> <FloatingLabel.Input id='name' /> <FloatingLabel.Label htmlFor='name'>Full Name</FloatingLabel.Label> </FloatingLabel> </Field> <Field> <FloatingLabel> <FloatingLabel.Input id='email' type='email' /> <FloatingLabel.Label htmlFor='email'>Email</FloatingLabel.Label> </FloatingLabel> <FieldDescription> We'll send a confirmation to this address. </FieldDescription> </Field> <Field> <FloatingLabel> <FloatingLabel.Input id='password' type='password' /> <FloatingLabel.Label htmlFor='password'>Password</FloatingLabel.Label> </FloatingLabel> <FieldDescription>Must be at least 8 characters.</FieldDescription> </Field> </FieldGroup> </FieldSet>

Props

FloatingLabel (root)

PropTypeDefaultDescription
childrenReact.ReactNodeMust contain .Input and .Label.
classNamestringAdditional CSS classes for the root wrapper.

FloatingLabel.Input

PropTypeDefaultDescription
...propsInputHTMLAttributesAll standard input props.
classNamestringAdditional CSS classes.

FloatingLabel.Label

PropTypeDefaultDescription
htmlForstringMatches the input id.
childrenReact.ReactNodeThe label text.
classNamestringAdditional CSS classes.
Last updated on