homedesign bitsexpandable search

Expandable Search with Rich Results

Published Feb 19, 2024

Search experience needed to handle both document and people results, while keeping interactions smooth and intuitive. I ended up with a responsive autocomplete that highlights matched terms and groups results by type, with keyboard navigation that feels natural whether you're searching through documents or contacts.

Implementation Details

"use client";
 
import { useState } from "react";
import { Search, User, File } from "lucide-react";
import { cn } from "@/lib/cn";
 
export default function SearchInterface() {
    const [query, setQuery] = useState("");
    const [selectedIndex, setSelectedIndex] = useState(0);
 
    return (
        <div className="w-full max-w-md mx-auto">
            <div className="relative">
                <input
                    type="text"
                    placeholder="Start typing..."
                    className="w-full px-10 py-2 rounded-full border border-gray-200 dark:border-gray-700 focus:outline-none focus:ring-2"
                    value={query}
                    onChange={(e) => setQuery(e.target.value)}
                />
                <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" />
                {query && (
                    <button
                        className="absolute right-3 top-1/2 -translate-y-1/2 text-sm text-gray-400"
                        onClick={() => setQuery("")}
                    >
                        Clear
                    </button>
                )}
            </div>
 
            {query && (
                <div className="mt-1 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 overflow-hidden">
                    <div className="p-2">
                        <div className="text-sm text-gray-500 dark:text-gray-400 mb-2">Documents</div>
                        <SearchResults type="documents" query={query} selectedIndex={selectedIndex} />
                        <div className="text-sm text-gray-500 dark:text-gray-400 mt-4 mb-2">People</div>
                        <SearchResults type="people" query={query} selectedIndex={selectedIndex} />
                    </div>
                </div>
            )}
        </div>
    );
}

09:00:03 PM

24th of January, 2025