DEV Community

preetham
preetham

Posted on

Custom or GenericSearch search in React Typescript

Here is the generic code where user needs to pass the actualdata and data (where both are the same array) so that we do not loose the actual data when user erases the search parameters.

Here I used tailwindcss in className

import React from 'react'

type Props<T extends { [key: string]: any }> = {
    data: T[];
    actualData: T[];
    onchange: (value: T[]) => void;
}

function GenericSearch<T extends { [key: string]: any }>({ onchange, data, actualData }: Props<T>) {

    const handleSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
        const query = event.target.value.toLowerCase();
        if (!query.length) {
            return onchange(actualData)
        }
        const searchedValue = data.filter((property, i) => {
            return Object.values(property).some(value =>
                value.toString().toLowerCase().includes(query)
            );
        });
        searchedValue.length !== 0 ? onchange(searchedValue) : onchange(actualData)
    }

    return (
        <label className="relative block">
            <span className="sr-only">Search</span>
            <span className="absolute inset-y-0 left-0 flex items-center pl-2">
                <svg
                    className="h-5 w-5 fill-slate-300"
                    viewBox="0 0 20 20"
                ></svg>
            </span>
            <input
                className="placeholder:italic text-gray-800 placeholder:text-slate-400 block bg-gray-100 w-full"
                placeholder="Search here..."
                type="text"
                name="search"
                onChange={handleSearch}
            />
        </label>
    )
}

export default GenericSearch
Enter fullscreen mode Exit fullscreen mode

in App.ts

let's take the this sample json data form (here

"data": [
{
"id": 1,
"name": "cerulean",
"year": 2000,
"color": "#98B2D1",
"pantone_value": "15-4020"
},
{
"id": 2,
"name": "fuchsia rose",
"year": 2001,
"color": "#C74375",
"pantone_value": "17-2031"
},
{
"id": 3,
"name": "true red",
"year": 2002,
"color": "#BF1932",
"pantone_value": "19-1664"
},
{
"id": 4,
"name": "aqua sky",
"year": 2003,
"color": "#7BC4C4",
"pantone_value": "14-4811"
},
{
"id": 5,
"name": "red turquoise",
"year": 2004,
"color": "#E2583E",
"pantone_value": "17-1456"
},
{
"id": 6,
"name": "blue turquoise",
"year": 2005,
"color": "#53B0AE",
"pantone_value": "15-5217"
}
]

const handleSearch = (value: objectType[]) => {
setFilterData(assignValuesObject(value));
};


<GenericSearch
data={filterData}
actualData={data}
onchange={handleSearch}
/>

for checking if our filter is working or not
<div>
{filterData.length && (
filterData.map((d: filterDataTypes) => {
return (
<div key={d.id + d.name}>{d.name}</div>
);
})
)
}
</div>

in utils.ts

`import { objectType } from "./types";

export const assignValuesObject = (values: objectType[]) =>
values.map((d, index: number) => {
return { ...d, id: index + d.description, isOpen: false };
});`

Top comments (0)