New

Search with Filters

A search input with filter chips, recent searches, and keyboard shortcut hint.

Forms & Inputsearchfilterchipsautocompleteinput

Dependencies

Other dependencies:

@/components/ui/input@/components/ui/badge@/components/ui/button@/components/ui/card

How to use this component

Copy the code below into your project. Make sure you have the required shadcn/ui dependencies installed. Then import and use the component in your pages or layouts.

Code

1"use client";
2
3import { useState } from 'react';
4import { Input } from '@/components/ui/input';
5import { Badge } from '@/components/ui/badge';
6import { Button } from '@/components/ui/button';
7import { Card } from '@/components/ui/card';
8import { Search, Clock, X, Command } from 'lucide-react';
9
10export default function SearchWithFilters() {
11 const [searchValue, setSearchValue] = useState('');
12 const [activeFilter, setActiveFilter] = useState('All');
13 const [recentSearches, setRecentSearches] = useState([
14 'React components',
15 'TypeScript tutorial',
16 'Tailwind CSS tips',
17 'UI design patterns'
18 ]);
19
20 const filters = ['All', 'Articles', 'Videos', 'Images', 'People'];
21
22 const removeRecent = (index: number) => {
23 setRecentSearches(prev => prev.filter((_, i) => i !== index));
24 };
25
26 return (
27 <Card className="w-full max-w-2xl mx-auto">
28 <CardContent className="p-6 space-y-4">
29 <div className="relative">
30 <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
31 <Input
32 placeholder="Search anything..."
33 value={searchValue}
34 onChange={e => setSearchValue(e.target.value)}
35 className="pl-10 pr-20"
36 />
37 <div className="absolute right-3 top-1/2 -translate-y-1/2 flex items-center gap-1">
38 <kbd className="px-2 py-1 text-xs font-mono bg-muted rounded border">
39 <Command className="w-3 h-3 inline mr-1" />
40 K
41 </kbd>
42 </div>
43 </div>
44
45 <div className="flex flex-wrap gap-2">
46 {filters.map(filter => (
47 <Badge
48 key={filter}
49 variant={activeFilter === filter ? 'default' : 'outline'}
50 className="cursor-pointer"
51 onClick={() => setActiveFilter(filter)}
52 >
53 {filter}
54 </Badge>
55 ))}
56 </div>
57
58 <div className="space-y-2">
59 <div className="flex items-center gap-2 text-sm text-muted-foreground">
60 <Clock className="w-4 h-4" />
61 <span>Recent Searches</span>
62 </div>
63 <div className="space-y-1">
64 {recentSearches.map((search, index) => (
65 <div
66 key={index}
67 className="flex items-center justify-between p-2 rounded hover:bg-muted group cursor-pointer"
68 >
69 <span className="text-sm">{search}</span>
70 <Button
71 variant="ghost"
72 size="sm"
73 className="opacity-0 group-hover:opacity-100 h-6 w-6 p-0"
74 onClick={() => removeRecent(index)}
75 >
76 <X className="w-3 h-3" />
77 </Button>
78 </div>
79 ))}
80 </div>
81 </div>
82 </CardContent>
83 </Card>
84 );
85}

Related Forms & Input Components

Command Palette

Search for a command to run...