๐ŸŽจ

UI Library

A collection of beautiful, reusable React components and CSS snippets built with Tailwind CSS and Framer Motion.

Inputs

Forms and input fields for collecting user data with various styles and validation states.

Default Input

InputDefault.tsxLanguage: tsx
export function DefaultInput() { return ( <div className="w-full max-w-sm"> <label className="block text-sm font-medium text-foreground mb-2">Email Address</label> <input type="email" placeholder="[email protected]" className="w-full px-4 py-2.5 rounded-xl border border-border bg-input text-foreground focus:outline-none focus:ring-2 focus:ring-accent/50 focus:border-accent transition-all duration-300 placeholder:text-muted/60" /> </div> ); }

With Icon

โŒ˜K
InputSearch.tsxLanguage: tsx
export function SearchInput() { return ( <div className="w-full max-w-sm relative group"> <div className="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none text-muted group-focus-within:text-accent transition-colors"> <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}> <path strokeLinecap="round" strokeLinejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /> </svg> </div> <input type="text" placeholder="Quick search..." className="w-full pl-11 pr-14 py-2.5 rounded-xl border border-border bg-input text-foreground focus:outline-none focus:ring-2 focus:ring-accent/20 focus:border-accent transition-all duration-300 placeholder:text-muted/60" /> <div className="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none"> <span className="flex items-center justify-center px-2 py-1 text-xs font-mono font-medium text-muted bg-black/5 dark:bg-white/5 border border-border rounded-md"> โŒ˜K </span> </div> </div> ); }

Password Show/Hide Toggle

InputPassword.tsxLanguage: tsx
import { useState } from 'react'; export function PasswordInput() { const [show, setShow] = useState(false); return ( <div className="w-full max-w-sm"> <label className="block text-sm font-medium text-foreground mb-2">Current Password</label> <div className="relative"> <input type={show ? "text" : "password"} placeholder="โ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ข" className="w-full pl-4 pr-12 py-2.5 rounded-xl border border-border bg-input text-foreground focus:outline-none focus:ring-2 focus:ring-accent/50 focus:border-accent transition-all duration-300 placeholder:text-muted/60" /> <button type="button" onClick={() => setShow(!show)} className="absolute inset-y-0 right-0 pr-4 flex items-center text-muted hover:text-foreground transition-colors focus:outline-none" > {show ? ( <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" /> </svg> ) : ( <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.543 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" /> </svg> )} </button> </div> </div> ); }

Floating Label Input

InputFloating.tsxLanguage: tsx
import { useState } from 'react'; export function FloatingLabelInput() { const [value, setValue] = useState(''); return ( <div className="w-full max-w-sm relative"> <input type="text" id="floating_input" className="block px-4 pb-2.5 pt-6 w-full text-foreground bg-input rounded-xl border border-border appearance-none focus:outline-none focus:ring-0 focus:border-accent peer transition-colors" placeholder=" " value={value} onChange={(e) => setValue(e.target.value)} /> <label htmlFor="floating_input" className="absolute text-sm text-muted duration-300 transform -translate-y-3 scale-75 top-4 z-10 origin-[0] left-4 peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-y-0 peer-focus:scale-75 peer-focus:-translate-y-3 peer-focus:text-accent pointer-events-none" > Company Name </label> </div> ); }

Prefix / Suffix Groups

https://.com
InputAddon.tsxLanguage: tsx
export function PrefixSuffixInput() { return ( <div className="w-full max-w-sm"> <label className="block text-sm font-medium text-foreground mb-2">Personal Website</label> <div className="flex relative rounded-xl shadow-sm"> <span className="inline-flex items-center px-4 rounded-l-xl border border-r-0 border-border bg-black/5 dark:bg-white/5 text-muted text-sm font-medium"> https:// </span> <input type="text" className="flex-1 min-w-0 block w-full px-4 py-2.5 rounded-none border border-border bg-input text-foreground focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent transition-all duration-300 placeholder:text-muted/60" placeholder="yourdomain" /> <span className="inline-flex items-center px-4 rounded-r-xl border border-l-0 border-border bg-black/5 dark:bg-white/5 text-muted text-sm font-medium"> .com </span> </div> </div> ); }

Error State

This username is already taken.

InputError.tsxLanguage: tsx
export function ErrorInput() { return ( <div className="w-full max-w-sm"> <label className="block text-sm font-medium text-red-500 mb-2">Username</label> <input type="text" defaultValue="dowy" className="w-full px-4 py-2.5 rounded-xl border border-red-500/50 bg-red-500/5 text-foreground focus:outline-none focus:ring-2 focus:ring-red-500/50 focus:border-red-500 transition-all duration-300" /> <p className="mt-2 text-sm text-red-500">This username is already taken.</p> </div> ); }