๐ŸŽจ

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