DEV Community

doruletzz
doruletzz

Posted on

 

🔎 Search Bar in React

...so, recently i've been needing a SearchBar component for my React Web Applications and i've kept postponing having a generic one that i can use in all my projects, but no more!

btw, this is also my first blog post to dev.to

Let's get started!

also if you'd like you can clone this project on github or check it out on stackblitz

Step 1: Initialize Project

Before we get started, we need to initialize a react application, we will use vite & npm, but feel free to use whatever tools you'd like.

Pick React with Typescript:

npm create vite@latest search-bar
cd search-bar
npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

Next we delete all other files in src/* except src/App.tsx & src/main.tsx

And we edit App.tsx to look something like this:

// src/App.tsx

export const App = () => {
    return <>Hello World</> 
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Step 2: SearchBar and Card components

Next up we create the 2 needed components, inside src/components/* for our application: <SearchBar/> & <Card/>

// src/components/Card/index.tsx

import { CardComponent } from './CardComponent';

const Card = CardComponent;

export default Card;

// src/components/Card/CardComponent.tsx

import React, { ReactNode } from 'react';

type CardComponentProps = {
    title: string;
    subtitle: string;
    slug?: string;
    children: ReactNode;
};

export const CardComponent = ({
    title,
    subtitle,
    slug,
    children,
}: CardComponentProps) => {
    return (
        <div id={slug} className='card'>
            <h6 className='title'>{title}</h6>
            {subtitle && <p className='subtitle'>{subtitle}</p>}
            <hr />
            {children && <div className='content'>{children}</div>}
        </div>
    );
};

Enter fullscreen mode Exit fullscreen mode

And we have our <Card/> component. We create the SearchBar in a similar way, with something like this:

// src/components/SearchBar/index.tsx
import { SearchBarComponent } from './SearchBarComponent';

const SearchBar = SearchBarComponent;

export default SearchBar;

// src/components/SearchBar/SearchBarComponent.tsx
import React, { ChangeEvent, Dispatch, SetStateAction } from 'react';

type SearchBarComponentProps = {
    label?: string;
    inputText: string;
    setInputText: Dispatch<SetStateAction<string>>;
};

export const SearchBarComponent = ({
    label,
    inputText,
    setInputText,
}: SearchBarComponentProps) => {
    const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
        const { value } = e.target;
        setInputText(value);
    };

    return (
        <div className='search-bar'>
            <label>{label}</label>
            <input value={inputText} onChange={handleChange} />
        </div>
    );
};
Enter fullscreen mode Exit fullscreen mode

And we are done, we've created our needed components.

Step 3: Tying it all together

Finally we are going to use a state that will be passed inside of the SearchBar components

We update App.tsx to look something like this:

// src/App.tsx
import React, { ReactNode, useState } from 'react';
import Card from './components/Card';
import SearchBar from './components/SearchBar';

type CardData = {
    title: string;
    subtitle: string;
    content: ReactNode;
};
// const data : CardData[] = ...

export const App = () => {
    const [searchText, setSearchText] = useState('');

    const filterCard = (e: CardData) =>
        e.title.toLowerCase().includes(searchText.toLowerCase());

    return (
        <>
            <SearchBar
                label='SEARCH'
                inputText={searchText}
                setInputText={setSearchText}
            />
            <div className='card-container'>
                {mockData.filter(filterCard).map((data, index) => (
                    <Card
                        key={index}
                        title={data.title}
                        subtitle={data.subtitle}
                    >
                        {data.content}
                    </Card>
                ))}
            </div>
        </>
    );
};

Enter fullscreen mode Exit fullscreen mode

Step 4 (extra): Styling it all

First we style the layout, meaning App.tsx by creating a App.css

// src/App.tsx

...
import './App.css';
...

// src/App.css

.search-bar {
    margin: 2rem auto;
    max-width: 80rem;
}

.card-container {
    display: flex;
    flex-wrap: wrap;

    gap: 2rem;

    max-width: 80rem;
    margin: auto;
}

.card-container > .card {
    flex-basis: 30%;
}
Enter fullscreen mode Exit fullscreen mode

Next up we style the SearchBar:

// src/components/SearchBar/SearchBarComponent.tsx
...
import './SearchBarComponent.css';
...
// src/components/SearchBar/SearchBarComponent.css
.search-bar {
    position: relative;
    max-width: 42rem;
}

.search-bar > input {
    width: 100%;
    padding: 0.75rem;
    padding-top: 1.75rem;

    background-color: var(--card-color);
    color: var(--text-color-900);

    font-size: 1.125rem;
    border: none;   
    border-radius: 0.5rem;
}

.search-bar > label {
    position: absolute;
    top: 0.5rem;
    left: 0.75rem;  
    font-size: 0.75rem;
    color: var(--text-color-800);
}
Enter fullscreen mode Exit fullscreen mode

& Finally we do the Card:

// src/components/Card/CardComponent.tsx
...
import './CardComponent.css';
...

// src/components/Card/CardComponent.css
.card { 
    background-color: var(--card-color);
    aspect-ratio: 4/5;

    display: flex;
    flex-direction: column;
    gap: 0.5rem;

    border-radius: 1rem;
    padding: 2rem;
}

.card > .title {
    color: var(--text-color-900);
    font-size: 1.5rem;
    font-weight: bold;

    margin: 0;

    overflow: hidden;
    text-overflow: ellipsis;
}


.card > .subtitle {
    color: var(--text-color-800);
    text-transform: uppercase;
    font-size: 1rem;

    margin: 0;

    overflow: hidden;
    text-overflow: ellipsis;
}

.card > hr {
    background-color: var(--text-color-800);

    width: 2rem;
    height: 0.05rem;

    margin: 0;
    border: none;
    margin-right: 100%;
}

.card > .content {
    color: var(--text-color-900);
    flex-grow: 1;

    overflow: hidden;
    text-overflow: ellipsis;
}
Enter fullscreen mode Exit fullscreen mode

And so we've created our SearchBar React Component.

Top comments (0)

Top Posts from the React Ecosystem

1. Changes In The Official React Documentation

The former React Docs Beta has been officially released as the updated React documentation at react.dev after years of hard work and refinement. Check out the brand new React Docs: What’s New in the Updated React Docs

2. CRA's Time is Over

React developer team has removed create-react-app (CRA) from official documentation rendering it no longer the default setup method for new projects. The bulky setup, slow, and outdated nature of CRA led to its removal: create-react-app is officially dead

3. How to Fetch Dev.to Articles for Your Portfolio

Integrate the articles of your Dev.to profile into your personal portfolio with either React, Vue, or Next.js by following these simple steps. It outlines how to include frontend to pull the information and correctly utilizes the Dev.to API: How to Fetch Your Dev.to Articles for Your Portfolio with React