typescriptbeginner
Search with Text Highlighting
Build a search component that highlights matching text within results using safe HTML rendering.
typescriptPress ⌘/Ctrl + Shift + C to copy
import { useMemo, useState } from 'react';
// Safely highlight matching text
function HighlightedText({ text, query }: { text: string; query: string }) {
if (!query.trim()) return <span>{text}</span>;
const escaped = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const regex = new RegExp(`(${escaped})`, 'gi');
const parts = text.split(regex);
return (
<span>
{parts.map((part, i) =>
regex.test(part) ? (
<mark key={i} className="bg-yellow-500/30 text-yellow-200 rounded px-0.5">
{part}
</mark>
) : (
<span key={i}>{part}</span>
),
)}
</span>
);
}
// Search list component
interface SearchItem {
id: string;
title: string;
description: string;
}
function SearchList({ items }: { items: SearchItem[] }) {
const [query, setQuery] = useState('');
const filtered = useMemo(() => {
if (!query.trim()) return items;
const lower = query.toLowerCase();
return items.filter(
(item) =>
item.title.toLowerCase().includes(lower) ||
item.description.toLowerCase().includes(lower),
);
}, [items, query]);
return (
<div className="space-y-3">
<input
type="search"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
className="w-full bg-[#111] border border-white/10 rounded-lg px-4 py-2
text-white placeholder:text-gray-500 focus:outline-none focus:border-blue-500"
/>
<p className="text-gray-500 text-sm">
{filtered.length} of {items.length} results
</p>
<ul className="space-y-2">
{filtered.map((item) => (
<li
key={item.id}
className="bg-[#111] border border-white/10 rounded-xl p-3
hover:bg-[#161616] hover:border-white/20 transition-colors"
>
<h3 className="text-white font-medium">
<HighlightedText text={item.title} query={query} />
</h3>
<p className="text-gray-400 text-sm mt-1">
<HighlightedText text={item.description} query={query} />
</p>
</li>
))}
</ul>
</div>
);
}
export { HighlightedText, SearchList };Use Cases
- Search results display
- Filtered lists with highlights
- Documentation search
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
typescriptintermediate
Toast Notification System
Build a toast notification system with auto-dismiss, stacking, animations, and severity levels.
Best for: User feedback notifications
#react#toast
typescriptbeginner
useDebounce — Debounced Value Hook
Debounce any rapidly-changing value with a configurable delay. Useful for search inputs and resize handlers.
Best for: Search-as-you-type
#hooks#debounce
typescriptintermediate
Error Boundary with Fallback UI
Class-based error boundary component that catches render errors and displays a customizable fallback UI.
Best for: Graceful error recovery
#error-boundary#error-handling
typescriptbeginner
usePrevious Hook
Track the previous value of any state or prop using a ref-based hook for comparison logic.
Best for: Detecting value changes
#hooks#state