diff options
Diffstat (limited to 'src/components/Search')
| -rw-r--r-- | src/components/Search/index.styled.ts | 88 | ||||
| -rw-r--r-- | src/components/Search/index.tsx | 67 |
2 files changed, 155 insertions, 0 deletions
diff --git a/src/components/Search/index.styled.ts b/src/components/Search/index.styled.ts new file mode 100644 index 0000000..c1344d5 --- /dev/null +++ b/src/components/Search/index.styled.ts @@ -0,0 +1,88 @@ +import styled from "styled-components"; + +export const Container = styled.div` + position: relative; + + width: 100%; + + margin-top: 5%; +`; + +export const SearchContainer = styled.div` + display: flex; + align-items: center; + + width: 100%; + height: 50px; + + border-color: ${({ theme }) => theme.border}; + border-width: 1px; + border-radius: 5px; + border-style: solid; + + color: ${({ theme }) => theme.text}; +`; + +export const SearchPadding = styled.div` + display: flex; + align-items: center; + + width: 100%; + + padding: 0 15px; +`; + +export const Input = styled.input` + width: 100%; + height: 100%; + margin: 0 10px; + + background-color: transparent; + border: none; + outline: none !important; + + color: ${({ theme }) => theme.text}; + font-size: 1rem; +`; + +export const ResultsContainer = styled.div` + position: absolute; + bottom: 50px; + z-index: 1; + + display: flex; + flex-direction: column; + justify-content: flex-end; + + width: 100%; + + overflow-y: scroll; +`; + +export const Result = styled.div` + padding: 1px 15px; + + background-color: ${({ theme }) => theme.background100}; + + border-color: ${({ theme }) => theme.border}; + border-width: 1px; + border-radius: 5px; + border-style: solid; + + color: ${({ theme }) => theme.text}; + + cursor: pointer; +`; + +export const ResultText = styled.p` + width: 100%; + + color: ${({ theme }) => theme.text}; + font-size: 0.9rem; + + user-select: none; + + &:hover { + opacity: 0.8; + } +`; diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx new file mode 100644 index 0000000..16f5c9e --- /dev/null +++ b/src/components/Search/index.tsx @@ -0,0 +1,67 @@ +import React from "react"; +import { event } from "react-ga"; +import { IoSearch } from "react-icons/io5"; +import { searchSong } from "../../helpers"; +import { Song } from "../../types/song"; + +import * as Styled from "./index.styled"; + +interface Props { + currentTry: number; + setSelectedSong: React.Dispatch<React.SetStateAction<Song | undefined>>; +} + +export function Search({ currentTry, setSelectedSong }: Props) { + const [value, setValue] = React.useState<string>(""); + const [results, setResults] = React.useState<Song[]>([]); + + React.useEffect(() => { + if (value) { + setResults(searchSong(value)); + } else if (value === "") { + setResults([]); + } + }, [value]); + + // clear value on selection + React.useEffect(() => { + setValue(""); + }, [currentTry]); + + return ( + <Styled.Container> + <Styled.ResultsContainer> + {results.map((song) => ( + <Styled.Result + key={song.youtubeId} + onClick={() => { + setSelectedSong(song); + setValue(`${song.artist} - ${song.name}`); + setResults([]); + + event({ + category: "Player", + action: "Chose song", + label: `${song.artist} - ${song.name}`, + }); + }} + > + <Styled.ResultText> + {song.artist} - {song.name} + </Styled.ResultText> + </Styled.Result> + ))} + </Styled.ResultsContainer> + <Styled.SearchContainer> + <Styled.SearchPadding> + <IoSearch size={20} /> + <Styled.Input + onChange={(e) => setValue(e.currentTarget.value)} + placeholder="Search" + value={value} + /> + </Styled.SearchPadding> + </Styled.SearchContainer> + </Styled.Container> + ); +} |
