요구사항
1. Emoji 리스트를 보여준다
2. 검색을 통해 필터링한다.
3. Emoji를 클릭하면 복사한다.
import { useState } from 'react';
import './App.css';
import EmojiList from './components/EmojiList';
import Header from './components/Header';
import SearchBox from './components/SearchBox';
import emojiJson from './data/emoji.json';
function App() {
const [keyword, setKeyword] = useState('');
return (
<div>
<Header />
<SearchBox onSearch={setKeyword} />
<EmojiList emojis={emojiJson} keyword={keyword} />
</div>
);
}
import styled from '@emotion/styled';
import React from 'react';
const Heading = styled.h1`
font-size: 32px;
text-align: center;
margin: 0;
`
export default function Header() {
return (
<Heading>Emoji Search</Heading>
);
}
import styled from '@emotion/styled';
import React from 'react';
const Input = styled.input`
width: 100%;
padding: 4px 6px;
border: 1px solid gray;
border-radius: 4px;
box-sizing: border-box;
`
export default function SearchBox({ onSearch }) {
return (
<div>
<Input onChange={(e) => onSearch(e.target.value)} />
</div>
);
}
import styled from '@emotion/styled';
import React from 'react';
const ListItem = styled.li`
display: flex;
align-items: center;
width: 100%;
padding: 8px 0;
border-bottom: 1px solid black;
cursor: pointer;
`
const Symbol = styled.div`
font-size: 24px;
margin-right: 16px;
`
const Title = styled.div`
width: 200px;
`
const Keywords = styled.div`
flex: 1;
`
export default function EmojiListItem({ emoji }) {
return (
<ListItem onClick={() => navigator.clipboard.writeText(emoji.symbol)}>
<Symbol>{emoji.symbol}</Symbol>
<Title>{emoji.title}</Title>
<Keywords>{emoji.keywords}</Keywords>
</ListItem>
);
}
import styled from '@emotion/styled';
import React from 'react';
import EmojiListItem from './EmojiListItem';
const Container = styled.ul`
width: 100%;
padding: 0;
`
export default function EmojiList({ emojis, keyword }) {
return (
<Container>
{emojis
.filter(
emoji =>
emoji.title.indexOf(keyword) >= 0 ||
emoji.keywords.indexOf(keyword) >= 0
)
.map(emoji => (
<EmojiListItem key={emoji.title} emoji={emoji} />
))}
</Container>
);
}