Yassine Ab
Yassine Ab

Reputation: 95

Animate the search list when typing on the searchbar (React)

What I'm trying to do: When a character is written in the search bar, the section is updated automatically after 0,8 sec of inaction (not typing), with the results corresponding to the research. The results appear with a slide effect to the top. The filters that do not match the research disappear with a fade out effect.

App.js

import React, { useState } from "react";
import SearchBar from "./SearchBar";
import "./App.scss";

function App() {
  const [searchValue, setSearchValue] = useState("");

  const users = [
    { name: "Jack", id: "1" },
    { name: "Lisa", id: "2" },
    { name: "Peter", id: "3" },
    { name: "Roman", id: "4" },
    { name: "Sarah", id: "5" },
    { name: "Eric", id: "6" },
    { name: "Fiora", id: "7" },
  ];

  const filterNames = ({ name }) => {
    return name.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1;
  };

  return (
    <div className="App">
      <h2>Search</h2>
      <SearchBar onSearch={setSearchValue} value={searchValue} />
      <ul>
        {users.filter(filterNames).map((user) => (
          <li className="user" key={user.id}>
            {user.name}
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

SearchBar

import React from "react";

function SearchBar(props) {
  return (
    <input
      type="text"
      onChange={(e) => props.onSearch(e.target.value)}
      value={props.value}
    />
  );
}

export default SearchBar;

App.scss

.user {
  list-style: none;
  animation: slide-in-bottom 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
}

@keyframes slide-in-bottom {
  0% {
    transform: translateY(1000px);
    opacity: 0;
  }
  100% {
    transform: translateY(0);
    opacity: 1;
  }
}

fade out effect

animation: fade-out 1s ease-out both;
@keyframes fade-out {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

I tried to add the slide in animation to the 'li' with className user but the animation only works in the first render and not when I type on the search bar.

Upvotes: 0

Views: 1544

Answers (1)

Vivek Doshi
Vivek Doshi

Reputation: 58553

Main issue with your code flow is, that you are removing elements,

how does someone can apply the css on removed element,

you need that element to give animation first,

So here is what you can do

// remove this

//   const filterNames = ({ name }) => {
//     return name.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1;
//   };

return (
    <div className="App">
      <h2>Search</h2>
      <SearchBar onSearch={setSearchValue} value={searchValue} />
      <ul>
        {users.map((user) => {
          // we can use it as like
          let classname = user.name.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1 ? 'user' : 'user removed';
          return <li className={classname} key={user.id}>
            {user.name}
          </li>
        })}
      </ul>
    </div>
);

And add some css for not matched user, to give removing effect.

WORKING DEMO

Upvotes: 1

Related Questions