<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: doruletzz</title>
    <description>The latest articles on DEV Community by doruletzz (@dorletz).</description>
    <link>https://dev.to/dorletz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1023142%2F22cbbf1e-e4c8-45e8-a56f-c3900cf9164a.jpeg</url>
      <title>DEV Community: doruletzz</title>
      <link>https://dev.to/dorletz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dorletz"/>
    <language>en</language>
    <item>
      <title>🔎 Search Bar in React</title>
      <dc:creator>doruletzz</dc:creator>
      <pubDate>Wed, 08 Feb 2023 16:37:43 +0000</pubDate>
      <link>https://dev.to/dorletz/search-bar-in-react-1jp2</link>
      <guid>https://dev.to/dorletz/search-bar-in-react-1jp2</guid>
      <description>&lt;p&gt;...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!&lt;/p&gt;

&lt;p&gt;btw, this is also &lt;em&gt;my first blog post&lt;/em&gt; to &lt;a href="https://dev.to/dorletz"&gt;dev.to&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's get started!
&lt;/h2&gt;

&lt;p&gt;also if you'd like you can clone this project on &lt;a href="https://github.com/doruletzz/search-bar"&gt;github&lt;/a&gt; or check it out on &lt;a href="https://stackblitz.com/edit/react-ts-j5ehry?file=index.tsx"&gt;stackblitz&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Initialize Project
&lt;/h4&gt;

&lt;p&gt;Before we get started, we need to initialize a react application, we will use &lt;a href="http://vitejs.dev"&gt;vite&lt;/a&gt; &amp;amp; &lt;a href="//npmjs.com"&gt;npm&lt;/a&gt;, but feel free to use whatever tools you'd like.&lt;/p&gt;

&lt;p&gt;Pick React with Typescript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm create vite@latest search-bar
cd search-bar
npm install
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we delete all other files in &lt;code&gt;src/*&lt;/code&gt; except &lt;code&gt;src/App.tsx&lt;/code&gt; &amp;amp; &lt;code&gt;src/main.tsx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And we edit &lt;code&gt;App.tsx&lt;/code&gt; to look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/App.tsx

export const App = () =&amp;gt; {
    return &amp;lt;&amp;gt;Hello World&amp;lt;/&amp;gt; 
};

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 2: SearchBar and Card components
&lt;/h4&gt;

&lt;p&gt;Next up we create the 2 needed components, inside src/components/* for our application: &lt;code&gt;&amp;lt;SearchBar/&amp;gt;&lt;/code&gt; &amp;amp; &lt;code&gt;&amp;lt;Card/&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 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) =&amp;gt; {
    return (
        &amp;lt;div id={slug} className='card'&amp;gt;
            &amp;lt;h6 className='title'&amp;gt;{title}&amp;lt;/h6&amp;gt;
            {subtitle &amp;amp;&amp;amp; &amp;lt;p className='subtitle'&amp;gt;{subtitle}&amp;lt;/p&amp;gt;}
            &amp;lt;hr /&amp;gt;
            {children &amp;amp;&amp;amp; &amp;lt;div className='content'&amp;gt;{children}&amp;lt;/div&amp;gt;}
        &amp;lt;/div&amp;gt;
    );
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we have our &lt;code&gt;&amp;lt;Card/&amp;gt;&lt;/code&gt; component. We create the SearchBar in a similar way, with something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 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&amp;lt;SetStateAction&amp;lt;string&amp;gt;&amp;gt;;
};

export const SearchBarComponent = ({
    label,
    inputText,
    setInputText,
}: SearchBarComponentProps) =&amp;gt; {
    const handleChange = (e: ChangeEvent&amp;lt;HTMLInputElement&amp;gt;) =&amp;gt; {
        const { value } = e.target;
        setInputText(value);
    };

    return (
        &amp;lt;div className='search-bar'&amp;gt;
            &amp;lt;label&amp;gt;{label}&amp;lt;/label&amp;gt;
            &amp;lt;input value={inputText} onChange={handleChange} /&amp;gt;
        &amp;lt;/div&amp;gt;
    );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we are done, we've created our needed components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Tying it all together
&lt;/h2&gt;

&lt;p&gt;Finally we are going to use a state that will be passed inside of the SearchBar components&lt;/p&gt;

&lt;p&gt;We update App.tsx to look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 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 = () =&amp;gt; {
    const [searchText, setSearchText] = useState('');

    const filterCard = (e: CardData) =&amp;gt;
        e.title.toLowerCase().includes(searchText.toLowerCase());

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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 4 (extra): Styling it all&lt;/p&gt;

&lt;p&gt;First we style the layout, meaning &lt;code&gt;App.tsx&lt;/code&gt; by creating a App.css&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 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 &amp;gt; .card {
    flex-basis: 30%;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next up we style the SearchBar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/components/SearchBar/SearchBarComponent.tsx
...
import './SearchBarComponent.css';
...
// src/components/SearchBar/SearchBarComponent.css
.search-bar {
    position: relative;
    max-width: 42rem;
}

.search-bar &amp;gt; 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 &amp;gt; label {
    position: absolute;
    top: 0.5rem;
    left: 0.75rem;  
    font-size: 0.75rem;
    color: var(--text-color-800);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;amp; Finally we do the Card:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 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 &amp;gt; .title {
    color: var(--text-color-900);
    font-size: 1.5rem;
    font-weight: bold;

    margin: 0;

    overflow: hidden;
    text-overflow: ellipsis;
}


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

    margin: 0;

    overflow: hidden;
    text-overflow: ellipsis;
}

.card &amp;gt; hr {
    background-color: var(--text-color-800);

    width: 2rem;
    height: 0.05rem;

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

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

    overflow: hidden;
    text-overflow: ellipsis;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And so we've created our SearchBar React Component.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
