๐จ
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>
);
}