Skip to content

Commit ad26c34

Browse files
authored
Merge pull request #4 from tshaddix/v0.0.0.1
V0.0.0.1
2 parents c1aea18 + a4745f0 commit ad26c34

32 files changed

+24160
-1
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,5 @@ typings/
5757
# dotenv environment variables file
5858
.env
5959

60+
example/bundle.js
61+
example/bundle.js.map

.npmignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
example/
2+
docs/

README.md

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,111 @@
11
# react-giphy-selector
2-
A search modal for picking the perfect giphy.
2+
A search and select React.JS component for picking the perfect giphy.
3+
4+
![Example selector](./docs/example_1.gif)
5+
6+
> This component is highly-customizable and only provides basic styling out-of-box. The example above includes simple customization to a few elements. You can view this example in `/example/src`.
7+
8+
## Table of Contents
9+
10+
- [Installation](#installation)
11+
- [Usage](#usage)
12+
13+
## Installation
14+
15+
You just install `react-giphy-selector` the good ole' fashion way through NPM:
16+
17+
```
18+
npm install --save react-giphy-selector
19+
```
20+
21+
## Usage
22+
23+
This package exports the `Selector` React component and then two helper `enums`:
24+
25+
```js
26+
import {Selector, ResultSort, Rating} from "react-giphy-selector";
27+
28+
```
29+
30+
- [Selector](#selector)
31+
- [Rating](#rating)
32+
- [ResultSort](#resultSort)
33+
34+
### Selector
35+
36+
The selector component contains all of the search, display, and selection logic. The only required properties are `apiKey` and `onGifSelected`.
37+
38+
```jsx
39+
<Selector
40+
apiKey={'myKey'}
41+
onGifSelected={this.saveGif} />
42+
```
43+
44+
That said, there are a bunch of props that allow you to make this component your own. Note: the `?` included at the end of a property name denotes it as optional.
45+
46+
- `apiKey: string`: [Your Giphy Project API Key](https://developers.giphy.com/).
47+
- `onGifSelected?: (gifObject: IGifObject) => void`: The function to fire when a gif search result has been selected. The `IGifObject` represents the full [GIF Object](https://developers.giphy.com/docs/#gif-object) returned via the Giphy API.
48+
- `rating?: Rating`: The maximum rating you want to allow in your search results. Use the exported [Rating](#rating) enum for help. Default: `Rating.G`.
49+
- `sort?: ResultSort`: The sort order of the search results. Use the helper enum [ResultSort](#resultsort). Default: `ResultSort.Relevant`.
50+
- `limit?: number`: The number of results to return. Default: `20`.
51+
- `suggestions?: string[]`: An array containing one-click searches to make it easy for your user. Will not show suggestions section if none are passed. Default: `[]`.
52+
- `queryInputPlaceholder?: string`: The placeholder text for the search bar text input. Default `'Enter search text'`.
53+
- `resultColumns?: number`: The number of columns to divide the search results into. Default: `3`.
54+
- `showGiphyMark?: boolean`: Indicates whether to show the "powered by Giphy" mark in the selector. This is required when [using a Giphy Production API Key](https://developers.giphy.com/docs/#production-key). Default: `true`.
55+
56+
#### Styling your Selector
57+
58+
There are a bunch of `props` to help you customize the style of the the selector. Both the `className` and the `style` methods are available. `react-giphy-selector` is very intentionally unopinionated about how exactly each section of the selector should look. Instead, the package offers a lot of customization and flexibility through the props below.
59+
60+
The images below will help you understand the nomenclature of the components:
61+
62+
![Diagram of component nomenclature for query form, suggestions, and footer](./docs/components_1.png)
63+
![Diagram of component nomenclature for search results](./docs/components_2.png)
64+
65+
Here are all the props available for styling the component:
66+
67+
- `queryFormClassName?: string`: Additional `className` for the query form section of the component. You can find the default style applied in `src/components/QueryForm.css`.
68+
- `queryFormInputClassName?: string`: Additional `className` for the text input in the query form. You can find the default style applied in `src/components/QueryForm.css`.
69+
- `queryFormSubmitClassName?: string`: Additional `className` for the submit button in the query form. You can find the default style applied in `src/components/QueryForm.css`.
70+
- `queryFormStyle?: object`: A style object to add to the query form style. You can find the default style applied in `src/components/QueryForm.css`.
71+
- `queryFormInputStyle?: object`: A style object to add to the text input in the query form. You can find the default style applied in `src/components/QueryForm.css`.
72+
- `queryFormSubmitStyle?: object`: A style object to add to the submit button in the query form. You can find the default style applied in `src/components/QueryForm.css`.
73+
- `queryFormSubmitContent?: string or Component`: You can pass in a `string` or your own component to render inside the submit button in the query form. This allows you to pass in things like custom icons. Default: `'Search'`.
74+
- `searchResultsClassName?: string`: Additional `className` for the search results component. You can find the default style in `src/components/SearchResults.css`.
75+
- `searchResultsStyle?: object`: A style object to the add to the search results container. You can find the default style in `src/components/SearchResults.css`.
76+
- `searchResultClassName?: string`: Additional `className` to add to a search result. Search results are `a` elements. You can find the default style in `src/components/SearchResult.css`.
77+
- `searchResultStyle?: object`: A style object to add to a search result. Search results are `a` elements. You can find the default style in `src/components/SearchResult.css`.
78+
- `suggestionsClassName?: string`: Additional `className` to add to the suggestions container. You can find the default style in `src/components/Suggestions.css`.
79+
- `suggestionsStyle?: object`: A style object to add to the suggestions container. You can find the default style in `src/components/Suggestions.css`.
80+
- `suggestionClassName?: string`: Additional `className` to add to a suggestion. This is an `a` element. You can find the default style in `src/components/Suggestion.css`.
81+
- `suggestionStyle?: object`: A style object to add to a suggestion. This is an `a` element. You can find the default style in `src/components/Suggestion.css`.
82+
- `loaderClassName?: string`: Additional `className` to add to the loader container. You can find the default style in `src/components/Selector.css`.
83+
- `loaderStyle?: object`: A style object to add to the loader container. You can find the default style in `src/components/Selector.css`.
84+
- `loaderContent?: string or Component`: You can pass in a `string` or customer component to display when results are loading. Default `'Loading'...`.
85+
- `searchErrorClassName?: string`: Additional `className` to add to the error message shown on broken searches. You can find the default style in `src/components/Selector.css`.
86+
- `searchErrorStyle?: object`: A style object to add to the error message shown on broken searches. You can find the default style in `src/components/Selector.css`.
87+
- `footerClassName?: string`: Additional `className` to add to footer of selector. You can find the default style in `src/components/Selector.css`.
88+
- `footerStyle?: object`: A style object to add to footer of selector. You can find the default style in `src/components/Selector.css`.
89+
90+
If you have a cool style you'd like to share, please [make an issue](https://github.com/tshaddix/react-giphy-selector/issues).
91+
92+
### Rating
93+
94+
The `Rating` enum contains all the possible ratings you can limit searches to:
95+
96+
```js
97+
Rating.Y
98+
Rating.G
99+
Rating.PG
100+
Rating.PG13
101+
Rating.R
102+
```
103+
104+
### ResultSort
105+
106+
The `ResultSort` enum contains the different sort methods supported by the Giphy API.
107+
108+
```js
109+
ResultSort.Recent // ordered by most recent
110+
ResultSort.Relevant // ordered by relevance
111+
```

docs/components_1.png

73.9 KB
Loading

docs/components_2.png

1.42 MB
Loading

docs/example_1.gif

9.42 MB
Loading

example/example.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>React Giphy Selector - Example</title>
6+
</head>
7+
<body>
8+
<div id="example"></div>
9+
10+
<!-- Main -->
11+
<script src="./bundle.js"></script>
12+
</body>
13+
</html>

example/src/example.css

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
.customQueryFormSubmit {
2+
background: #0097cf;
3+
color: #fff;
4+
border: 0;
5+
padding: 10px 20px;
6+
font-size: 16px;
7+
font-weight: bold;
8+
}
9+
10+
.customQueryFormInput {
11+
padding-left: 10px;
12+
padding-right: 10px;
13+
border: 1px solid #e0e0e0;
14+
border-right: 0;
15+
box-shadow: none;
16+
}
17+
18+
.customSearchResults {
19+
max-height: 400px;
20+
margin-top: 10px;
21+
margin-bottom: 10px;
22+
}
23+
24+
/********************************
25+
CSS classes for example fake modal
26+
********************************/
27+
28+
body {
29+
background: #333;
30+
font-family: sans-serif;
31+
}
32+
33+
.modal {
34+
max-width: 600px;
35+
margin: 60px auto;
36+
background: #fff;
37+
padding: 20px;
38+
border-bottom: 5px solid #111;
39+
}

example/src/example.tsx

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { Selector, Rating } from "../../lib";
2+
import * as React from "react";
3+
import * as ReactDOM from "react-dom";
4+
5+
const customStyle = require("./example.css");
6+
7+
// feel free to change these :)
8+
const suggestions = [
9+
"watching",
10+
"quiz",
11+
"stop it",
12+
"nice one",
13+
"learning",
14+
"reading",
15+
"working"
16+
];
17+
18+
interface IExampleProps {
19+
suggestions: string[];
20+
}
21+
22+
interface IExampleState {
23+
apiKey: string;
24+
isKeySubmitted: boolean;
25+
}
26+
27+
class ExampleApp extends React.Component<IExampleProps, IExampleState> {
28+
state: IExampleState;
29+
30+
constructor(props: IExampleProps) {
31+
super(props);
32+
33+
this.state = {
34+
apiKey: "",
35+
isKeySubmitted: false
36+
};
37+
38+
this.onKeyChange = this.onKeyChange.bind(this);
39+
this.onKeySubmit = this.onKeySubmit.bind(this);
40+
this.onGifSelected = this.onGifSelected.bind(this);
41+
}
42+
43+
public onKeyChange(event: any): void {
44+
this.setState({ apiKey: event.target.value });
45+
}
46+
47+
public onKeySubmit(event: any): void {
48+
event.preventDefault();
49+
50+
this.setState({
51+
isKeySubmitted: true
52+
});
53+
}
54+
55+
public onGifSelected(gifObject: any): void {
56+
alert(`You selected a gif! id: ${gifObject.id}`);
57+
}
58+
59+
public render(): JSX.Element {
60+
const { apiKey, isKeySubmitted } = this.state;
61+
const { suggestions } = this.props;
62+
63+
if (!isKeySubmitted) {
64+
return (
65+
<form onSubmit={this.onKeySubmit}>
66+
<input
67+
type="text"
68+
placeholder="Enter your Giphy API Key"
69+
value={apiKey}
70+
onChange={this.onKeyChange}
71+
/>
72+
<button type="submit">Set API Key</button>
73+
</form>
74+
);
75+
}
76+
77+
return (
78+
<div className={customStyle.modal}>
79+
<Selector
80+
apiKey={apiKey}
81+
suggestions={suggestions}
82+
onGifSelected={this.onGifSelected}
83+
rating={Rating.G}
84+
limit={40}
85+
queryFormInputClassName={customStyle.customQueryFormInput}
86+
queryFormSubmitClassName={customStyle.customQueryFormSubmit}
87+
searchResultsClassName={customStyle.customSearchResults}
88+
searchResultClassName={customStyle.customSearchResult}
89+
/>
90+
</div>
91+
);
92+
}
93+
}
94+
95+
ReactDOM.render(
96+
<ExampleApp suggestions={suggestions} />,
97+
document.getElementById("example")
98+
);

example/webpack.config.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module.exports = {
2+
entry: "./example/src/example.tsx",
3+
output: {
4+
filename: "bundle.js",
5+
path: __dirname
6+
},
7+
8+
// Enable sourcemaps for debugging webpack's output.
9+
devtool: "source-map",
10+
11+
resolve: {
12+
// Add '.ts' and '.tsx' as resolvable extensions.
13+
extensions: [".ts", ".tsx", ".js", ".json"]
14+
},
15+
16+
module: {
17+
rules: [
18+
// All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
19+
{ test: /\.tsx?$/, loader: "awesome-typescript-loader" },
20+
21+
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
22+
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" },
23+
24+
{
25+
test: /\.css$/,
26+
loader: ["style-loader", "css-loader?sourceMap&modules"]
27+
}
28+
]
29+
}
30+
};

0 commit comments

Comments
 (0)