MultiSelect
multiselect-1779394345235.tsx
'use client'
import { useState, useRef } from 'react'
const OPTIONS = ['React','Vue','Angular','Svelte','Next.js','Nuxt','Remix','Astro']
export default function MultiSelect({ options = OPTIONS, placeholder = 'Select frameworks...' }) {
const [open, setOpen] = useState(false)
const [selected, setSelected] = useState([])
const [search, setSearch] = useState('')
const filtered = options.filter(o => o.toLowerCase().includes(search.toLowerCase()))
const toggle = (opt) => setSelected(s => s.includes(opt) ? s.filter(x => x!==opt) : [...s, opt])
const all = selected.length === options.length
return (
<div style={{ position:'relative', maxWidth:'320px' }}>
<div onClick={() => setOpen(!open)} style={{
display:'flex', flexWrap:'wrap', gap:'4px', padding:'8px 12px',
border:'2px solid ' + (open?'#6d28d9':'#e2e8f0'), borderRadius:'10px',
cursor:'pointer', minHeight:'44px', alignItems:'center', background:'#fff',
}}>
{selected.length === 0 && <span style={{ color:'#94a3b8', fontSize:'14px' }}>{placeholder}</span>}
{selected.map(s => (
<span key={s} style={{ background:'#ede9fe', color:'#6d28d9', padding:'2px 8px', borderRadius:'6px', fontSize:'12px', fontWeight:600, display:'flex', alignItems:'center', gap:'4px' }}>
{s}
<button onClick={e=>{e.stopPropagation();toggle(s)}} style={{ background:'none', border:'none', color:'#7c3aed', cursor:'pointer', fontSize:'14px', padding:0 }}>×</button>
</span>
))}
<span style={{ marginLeft:'auto', color:'#94a3b8', fontSize:'14px' }}>{open?'▲':'▼'}</span>
</div>
{open && (
<div style={{ position:'absolute', top:'calc(100%+4px)', left:0, right:0, background:'#fff', border:'1px solid #e2e8f0', borderRadius:'10px', boxShadow:'0 8px 30px rgba(0,0,0,0.1)', zIndex:100, overflow:'hidden', marginTop:'4px' }}>
<div style={{ padding:'10px' }}>
<input value={search} onChange={e=>setSearch(e.target.value)} placeholder="Search..." style={{ width:'100%', border:'1px solid #e2e8f0', borderRadius:'6px', padding:'6px 10px', fontSize:'13px', outline:'none', boxSizing:'border-box' }} />
</div>
<div onClick={()=>setSelected(all?[]:options)} style={{ padding:'8px 14px', fontSize:'13px', fontWeight:600, color:'#6d28d9', borderBottom:'1px solid #f1f5f9', cursor:'pointer', background:'#faf5ff' }}>
{all ? 'Deselect All' : 'Select All'}
</div>
<div style={{ maxHeight:'200px', overflowY:'auto' }}>
{filtered.map(opt => (
<div key={opt} onClick={()=>toggle(opt)} style={{
display:'flex', alignItems:'center', gap:'10px', padding:'10px 14px',
cursor:'pointer', fontSize:'14px', color:selected.includes(opt)?'#6d28d9':'#374151',
background:selected.includes(opt)?'#faf5ff':'transparent',
}}>
<div style={{ width:'16px', height:'16px', borderRadius:'4px', border:'2px solid '+(selected.includes(opt)?'#6d28d9':'#cbd5e1'), background:selected.includes(opt)?'#6d28d9':'transparent', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
{selected.includes(opt) && <span style={{ color:'#fff', fontSize:'10px' }}>✓</span>}
</div>
{opt}
</div>
))}
</div>
</div>
)}
</div>
)
}Component info
CategoryInputs & Forms
Frameworkreact
TierFREE
Views0
Copies0
About
Multi-select dropdown with search, badges and select-all option
More from Inputs & Forms
'use client';
import { useState, useEffect } from 'react';
interface Tag {
id: number;
name: string;
}
const TagInput = () => {
const [tags, setTags] = useState<Tag[]>([]);
const [inputValue, setInputValue] = useState('');
const [suggestTagInput
Inputs & Forms
'use client';
import React, { useState } from 'react';
interface File {
name: string;
size: number;
progress: number;
}
const FileUpload = () => {
const [dragOver, setDragOver] = useState(false);
const [files, setFiles] = useState<File[]FileUpload
Inputs & Forms
import React, { useState } from 'react';
const OTPInput = () => {
const [otp, setOtp] = useState(new Array(6).fill(''));
const [activeIndex, setActiveIndex] = useState(0);
const handleChange = (e, index) => {
const value = e.target.value;OTPInput
Inputs & Forms
'use client';
import React, { useState } from 'react';
interface RangeSliderProps {
min: number;
max: number;
defaultValue: [number, number];
}
const RangeSlider: React.FC<RangeSliderProps> = ({ min, max, defaultValue }) => {
const [minValRangeSlider
Inputs & Forms