๐จ
UI Library
A collection of beautiful, reusable React components and CSS snippets built with Tailwind CSS and Framer Motion.
Select Menus
Custom dropdown menus and selection interfaces.
Default Select
Select.tsxLanguage: tsx
export function DefaultSelect() {
return (
<div className="w-full max-w-sm relative">
<label className="block text-sm font-medium text-foreground mb-2">Select an option</label>
<div className="relative">
<select defaultValue="" className="w-full px-4 py-2.5 rounded-xl border border-border bg-input text-foreground appearance-none focus:outline-none focus:ring-2 focus:ring-accent/50 focus:border-accent transition-all duration-300 pr-10">
<option value="" disabled>Select from list...</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<div className="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none text-muted">
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
</svg>
</div>
</div>
</div>
);
}Status Indicator Select
SelectStatus.tsxLanguage: tsx
import { useState } from 'react';
export function StatusSelect() {
const [status, setStatus] = useState('active');
const statusColors: Record<string, string> = {
active: "bg-green-500",
paused: "bg-yellow-500",
archived: "bg-muted"
};
return (
<div className="w-full max-w-sm relative">
<label className="block text-sm font-medium text-foreground mb-2">Project Status</label>
<div className="relative">
<div className="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none">
<span className={`w-2.5 h-2.5 rounded-full ${statusColors[status]}`}></span>
</div>
<select
value={status}
onChange={(e) => setStatus(e.target.value)}
className="w-full pl-10 pr-10 py-2.5 rounded-xl border border-border bg-input text-foreground appearance-none focus:outline-none focus:ring-2 focus:ring-accent/50 focus:border-accent transition-all duration-300"
>
<option value="active">Active</option>
<option value="paused">Paused</option>
<option value="archived">Archived</option>
</select>
<div className="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none text-muted">
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 9l4-4 4 4m0 6l-4 4-4-4" />
</svg>
</div>
</div>
</div>
);
}Custom Searchable Select
SelectSearchable.tsxLanguage: tsx
import { useState, useRef, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
const TABS = [
{ id: 'design', label: 'Design System', icon: '๐จ' },
{ id: 'api', label: 'API Gateway', icon: 'โก' },
{ id: 'db', label: 'Database Cluster', icon: '๐๏ธ' },
{ id: 'auth', label: 'Authentication', icon: '๐' }
];
export function SearchableSelect() {
const [isOpen, setIsOpen] = useState(false);
const [search, setSearch] = useState('');
const [selected, setSelected] = useState('');
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
if (ref.current && !ref.current.contains(event.target as Node)) setIsOpen(false);
}
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);
const filtered = TABS.filter(t => t.label.toLowerCase().includes(search.toLowerCase()));
const selectedItem = TABS.find(t => t.id === selected);
return (
<div className="w-full max-w-sm" ref={ref}>
<label className="block text-sm font-medium text-foreground mb-2">Assigned Project</label>
<div className="relative">
<button
onClick={() => setIsOpen(!isOpen)}
className="w-full flex items-center justify-between px-4 py-2.5 bg-input border border-border rounded-xl hover:bg-black/5 dark:hover:bg-white/5 transition-colors focus:ring-2 focus:ring-accent focus:outline-none text-left"
>
<div className="flex items-center gap-2 truncate">
{selectedItem ? (
<>
<span>{selectedItem.icon}</span>
<span className="font-medium text-foreground">{selectedItem.label}</span>
</>
) : (
<span className="text-muted">Select project...</span>
)}
</div>
<svg className={`w-4 h-4 text-muted transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</button>
<AnimatePresence>
{isOpen && (
<motion.div
initial={{ opacity: 0, y: -10, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
exit={{ opacity: 0, y: -10, scale: 0.95 }}
transition={{ duration: 0.15 }}
className="absolute z-20 w-full mt-2 bg-input border border-border rounded-xl shadow-2xl overflow-hidden"
>
<div className="p-2 border-b border-border">
<input
type="text"
placeholder="Search projects..."
value={search}
onChange={(e) => setSearch(e.target.value)}
className="w-full px-3 py-2 bg-black/5 dark:bg-white/5 border border-transparent rounded-lg text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-accent focus:border-accent"
/>
</div>
<div className="max-h-56 overflow-y-auto p-1">
{filtered.length > 0 ? filtered.map(item => (
<button
key={item.id}
onClick={() => {
setSelected(item.id);
setIsOpen(false);
setSearch('');
}}
className={`w-full flex items-center justify-between px-3 py-2.5 rounded-lg text-sm transition-colors text-left ${selected === item.id ? 'bg-accent/10 text-accent font-medium' : 'hover:bg-black/5 dark:hover:bg-white/5 text-foreground'}`}
>
<div className="flex items-center gap-2">
<span>{item.icon}</span>
<span>{item.label}</span>
</div>
{selected === item.id && (
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" /></svg>
)}
</button>
)) : (
<div className="p-4 text-center text-sm text-muted">No results found.</div>
)}
</div>
</motion.div>
)}
</AnimatePresence>
</div>
</div>
);
}Native Select Style
SelectNative.tsxLanguage: tsx
export function NativeSelect() {
return (
<div className="w-full max-w-sm">
<label className="block text-sm font-medium text-foreground mb-2">Native Style</label>
<select 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">
<optgroup label="Group 1">
<option value="1">Item A</option>
<option value="2">Item B</option>
</optgroup>
<optgroup label="Group 2">
<option value="3">Item C</option>
<option value="4">Item D</option>
</optgroup>
</select>
</div>
);
}