Reputation: 95
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
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.
Upvotes: 1