React for Designers and PMs
Search contacts
A React component that filters a list of contacts by name or number as you type in a search input.
LLM Written
Human Reviewed
Output
Type here to search
Alice
123-456-7890
Bob
987-654-3210
Charlie
555-555-5555
David
111-222-3333
Eve
444-444-4444
Frank
666-666-6666
File Structure
├── src
` `├── App.tsx `← we are here`
` `├── index.css
` `└── main.tsxDistraction free code
const [contacts, setContacts] = useState([
{ id: 1, name: 'Alice', number: '123-456-7890', isFav: true },
{ id: 2, name: 'Bob', number: '987-654-3210', isFav: false },
...
]);
const [search, setSearch] = useState('');
const filteredContacts = contacts.filter(
(contact) =>
contact.name.toLowerCase().includes(search.toLowerCase()) ||
contact.number.includes(search)
);
{/*Search input*/}
<input
value={search}
onChange={(e) => setSearch(e.target.value)}
/>
{/*Empty state*/}
{filteredContacts.length === 0 && <p>No contacts found</p>}
{/*Filtered list*/}
{filteredContacts.map((contact) => (
<div key={contact.id}>
<p>{contact.name}</p>
<p>{contact.number}</p>
{contact.isFav && <Star />}
</div>
))}Code
'use client';
import { Search, User, Star } from 'lucide-react';
import { useState } from 'react';
export default function Home() {
const [contacts, setContacts] = useState([
{ id: 1, name: 'Alice', number: '123-456-7890', isFav: true },
{ id: 2, name: 'Bob', number: '987-654-3210', isFav: false },
{ id: 3, name: 'Charlie', number: '555-555-5555', isFav: false },
{ id: 4, name: 'David', number: '111-222-3333', isFav: true },
{ id: 5, name: 'Eve', number: '444-444-4444', isFav: false },
{ id: 6, name: 'Frank', number: '666-666-6666', isFav: false },
]);
const [search, setSearch] = useState('');
const filteredContacts = contacts.filter(
(contact) =>
contact.name.toLowerCase().includes(search.toLowerCase()) ||
contact.number.includes(search)
);
return (
<>
<div className='flex items-center gap-2 bg-white border border-gray-100 px-4 py-3'>
<Search size={18} className='text-gray-400' />
<input
type='text'
placeholder='Search by name or number...'
value={search}
onChange={(e) => setSearch(e.target.value)}
className='w-full outline-none text-sm text-gray-700 placeholder-gray-400'
/>
</div>
{filteredContacts.length === 0 && (
<p className='text-gray-400 text-sm p-6'>No contacts found</p>
)}
{filteredContacts.map((contact) => (
<div key={contact.id} className='flex items-center gap-4 bg-white border border-gray-100 px-4'>
<User size={24} className='text-blue-500' />
<p className='py-6'>{contact.name}</p>
<p className='text-gray-500'>{contact.number}</p>
{contact.isFav && <Star size={20} className='fill-orange-300 stroke-orange-400' />}
</div>
))}
</>
);
}Layer Visualisation
Layers
Approximation of how this code would look in Figma's layer panel.
Home
ReactImport
IconImport
contacts"[{ id, name, number, isFav }, ...]"
search"''"
filteredContacts
contactsData"[{ id: 1, name: 'Alice', isFav: true }, ...]"
SearchContactsFragment
SearchBar
SearchIcon
SearchInput
showEmptyStateIfNoResults
EmptyStateMessage"No contacts found"
ContactRow
UserIcon
ContactName"{contact.name}"
ContactNumber"{contact.number}"
showStarIfFavourite
FavouriteStarIcon
Select a layer to inspect
What's new and what's happening?
New!