├── .gitignore
├── LICENSE
├── README.md
├── package.json
├── public
├── favicon.ico
├── index.html
└── manifest.json
├── src
├── App.css
├── App.js
├── App.test.js
├── EmojiResultRow.css
├── EmojiResultRow.js
├── EmojiResults.css
├── EmojiResults.js
├── Header.css
├── Header.js
├── SearchInput.css
├── SearchInput.js
├── emojiList.json
├── filterEmoji.js
├── index.css
├── index.js
└── logo.svg
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | node_modules
5 |
6 | # testing
7 | coverage
8 |
9 | # production
10 | build
11 |
12 | # misc
13 | .DS_Store
14 | npm-debug.log
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Andrew H Farmer
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Emoji Search
2 | ---
3 |
4 | Created with *create-react-app*. See the [full create-react-app guide](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md).
5 |
6 |
7 |
8 | Install
9 | ---
10 |
11 | `npm install`
12 |
13 |
14 |
15 | Usage
16 | ---
17 |
18 | `npm start`
19 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "emoji-search",
3 | "version": "0.1.0",
4 | "license": "MIT",
5 | "homepage": "http://ahfarmer.github.io/emoji-search",
6 | "devDependencies": {
7 | "gh-pages": "^2.0.1",
8 | "prettier": "^1.17.1",
9 | "react-scripts": "^3.0.1"
10 | },
11 | "dependencies": {
12 | "clipboard": "^2.0.4",
13 | "github-fork-ribbon-css": "^0.2.1",
14 | "react": "^16.8.6",
15 | "react-dom": "^16.8.6"
16 | },
17 | "scripts": {
18 | "start": "react-scripts start",
19 | "build": "react-scripts build",
20 | "test": "react-scripts test --env=jsdom",
21 | "eject": "react-scripts eject",
22 | "deploy": "gh-pages -d build"
23 | },
24 | "browserslist": {
25 | "production": [
26 | ">0.2%",
27 | "not dead",
28 | "not op_mini all"
29 | ],
30 | "development": [
31 | "last 1 chrome version",
32 | "last 1 firefox version",
33 | "last 1 safari version"
34 | ]
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/andrewagain/emoji-search/609bda65d274fdc0f8b7f73ec2f2025c4d58d49f/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Emoji Search
9 |
10 |
11 |
14 |
15 |
19 | Fork me on GitHub
20 |
21 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Emoji Search",
3 | "name": "Emoji Search Example App",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-intro {
18 | font-size: large;
19 | }
20 |
21 | @keyframes App-logo-spin {
22 | from {
23 | transform: rotate(0deg);
24 | }
25 | to {
26 | transform: rotate(360deg);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from "react";
2 | import Header from "./Header";
3 | import SearchInput from "./SearchInput";
4 | import EmojiResults from "./EmojiResults";
5 | import filterEmoji from "./filterEmoji";
6 |
7 | export default class App extends PureComponent {
8 | constructor(props) {
9 | super(props);
10 | this.state = {
11 | filteredEmoji: filterEmoji("", 20)
12 | };
13 | }
14 |
15 | handleSearchChange = event => {
16 | this.setState({
17 | filteredEmoji: filterEmoji(event.target.value, 20)
18 | });
19 | };
20 |
21 | render() {
22 | return (
23 |
24 |
25 |
26 |
27 |
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import App from "./App";
4 |
5 | it("renders without crashing", () => {
6 | const div = document.createElement("div");
7 | ReactDOM.render(, div);
8 | });
9 |
--------------------------------------------------------------------------------
/src/EmojiResultRow.css:
--------------------------------------------------------------------------------
1 | .component-emoji-result-row {
2 | border-bottom: 1px solid #ccc;
3 | padding: 10px;
4 | height: 32px;
5 | position: relative;
6 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
7 | cursor: pointer;
8 | }
9 |
10 | .component-emoji-result-row:hover {
11 | background-color: #eee;
12 | }
13 |
14 | .component-emoji-result-row img {
15 | width: 32px;
16 | height: 32px;
17 | padding-right: 10px;
18 | }
19 |
20 | .component-emoji-result-row .title {
21 | position: relative;
22 | top: -8px;
23 | }
24 |
25 | .component-emoji-result-row .info {
26 | float: right;
27 | position: relative;
28 | top: 8px;
29 | right: 10px;
30 | color: #ccc;
31 | display: none;
32 | }
33 |
34 | .component-emoji-result-row:hover .info {
35 | display: inline-block;
36 | }
37 |
--------------------------------------------------------------------------------
/src/EmojiResultRow.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from "react";
2 | import PropTypes from "prop-types";
3 | import "./EmojiResultRow.css";
4 |
5 | export default class EmojiResultsRow extends PureComponent {
6 | static propTypes = {
7 | title: PropTypes.string,
8 | symbol: PropTypes.string
9 | };
10 |
11 | render() {
12 | const codePointHex = this.props.symbol.codePointAt(0).toString(16);
13 | const src = `//cdn.jsdelivr.net/emojione/assets/png/${codePointHex}.png`;
14 | return (
15 |
19 |

20 |
{this.props.title}
21 |
Click to copy emoji
22 |
23 | );
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/EmojiResults.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/andrewagain/emoji-search/609bda65d274fdc0f8b7f73ec2f2025c4d58d49f/src/EmojiResults.css
--------------------------------------------------------------------------------
/src/EmojiResults.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from "react";
2 | import PropTypes from "prop-types";
3 | import Clipboard from "clipboard";
4 |
5 | import EmojiResultRow from "./EmojiResultRow";
6 | import "./EmojiResults.css";
7 |
8 | export default class EmojiResults extends PureComponent {
9 | static propTypes = {
10 | emojiData: PropTypes.array
11 | };
12 |
13 | componentDidMount() {
14 | this.clipboard = new Clipboard(".copy-to-clipboard");
15 | }
16 |
17 | componentWillUnmount() {
18 | this.clipboard.destroy();
19 | }
20 |
21 | render() {
22 | return (
23 |
24 | {this.props.emojiData.map(emojiData => (
25 |
30 | ))}
31 |
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Header.css:
--------------------------------------------------------------------------------
1 | .component-header {
2 | padding: 15px;
3 | position: relative;
4 | font-weight: normal;
5 | font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
6 | font-size: 32px;
7 | text-align: center;
8 | color: #333;
9 | }
10 |
11 | .component-header img {
12 | position: relative;
13 | top: 6px;
14 | padding: 0 14px;
15 | }
16 |
--------------------------------------------------------------------------------
/src/Header.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from "react";
2 | import "./Header.css";
3 |
4 | export default class Header extends PureComponent {
5 | render() {
6 | return (
7 |
8 |
14 | Emoji Search
15 |
21 |
22 | );
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/SearchInput.css:
--------------------------------------------------------------------------------
1 | .component-search-input {
2 | border-bottom: 1px solid #ccc;
3 | }
4 |
5 | .component-search-input > div {
6 | margin: 0 10px 10px 10px;
7 | }
8 |
9 | .component-search-input input {
10 | border-radius: 4px;
11 | border: 1px solid #bbb;
12 | box-sizing: border-box;
13 | font-size: 18px;
14 | padding: 10px 8px;
15 | width: 100%;
16 | }
17 |
--------------------------------------------------------------------------------
/src/SearchInput.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from "react";
2 | import PropTypes from "prop-types";
3 |
4 | import "./SearchInput.css";
5 |
6 | export default class SearchInput extends PureComponent {
7 | static propTypes = {
8 | textChange: PropTypes.func
9 | };
10 |
11 | handleChange = event => {
12 | this.props.textChange(event);
13 | };
14 |
15 | render() {
16 | return (
17 |
22 | );
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/filterEmoji.js:
--------------------------------------------------------------------------------
1 | import emojiList from "./emojiList.json";
2 |
3 | export default function filterEmoji(searchText, maxResults) {
4 | return emojiList
5 | .filter(emoji => {
6 | if (emoji.title.toLowerCase().includes(searchText.toLowerCase())) {
7 | return true;
8 | }
9 | if (emoji.keywords.includes(searchText)) {
10 | return true;
11 | }
12 | return false;
13 | })
14 | .slice(0, maxResults);
15 | }
16 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
7 | body .github-fork-ribbon:before {
8 | background-color: #333;
9 | }
10 |
11 | @media screen and (max-width: 500px) {
12 | .github-fork-ribbon {
13 | display: none;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import App from "./App";
4 | import "./index.css";
5 | import "github-fork-ribbon-css/gh-fork-ribbon.css";
6 |
7 | ReactDOM.render(, document.getElementById("root"));
8 |
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------