Skip to content

Commit

Permalink
Merge pull request #4 from tshaddix/v0.0.0.1
Browse files Browse the repository at this point in the history
V0.0.0.1
  • Loading branch information
tshaddix authored Jan 7, 2018
2 parents c1aea18 + a4745f0 commit ad26c34
Show file tree
Hide file tree
Showing 32 changed files with 24,160 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,5 @@ typings/
# dotenv environment variables file
.env

example/bundle.js
example/bundle.js.map
2 changes: 2 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
example/
docs/
111 changes: 110 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,111 @@
# react-giphy-selector
A search modal for picking the perfect giphy.
A search and select React.JS component for picking the perfect giphy.

![Example selector](./docs/example_1.gif)

> 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`.
## Table of Contents

- [Installation](#installation)
- [Usage](#usage)

## Installation

You just install `react-giphy-selector` the good ole' fashion way through NPM:

```
npm install --save react-giphy-selector
```

## Usage

This package exports the `Selector` React component and then two helper `enums`:

```js
import {Selector, ResultSort, Rating} from "react-giphy-selector";

```

- [Selector](#selector)
- [Rating](#rating)
- [ResultSort](#resultSort)

### Selector

The selector component contains all of the search, display, and selection logic. The only required properties are `apiKey` and `onGifSelected`.

```jsx
<Selector
apiKey={'myKey'}
onGifSelected={this.saveGif} />
```

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.

- `apiKey: string`: [Your Giphy Project API Key](https://developers.giphy.com/).
- `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.
- `rating?: Rating`: The maximum rating you want to allow in your search results. Use the exported [Rating](#rating) enum for help. Default: `Rating.G`.
- `sort?: ResultSort`: The sort order of the search results. Use the helper enum [ResultSort](#resultsort). Default: `ResultSort.Relevant`.
- `limit?: number`: The number of results to return. Default: `20`.
- `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: `[]`.
- `queryInputPlaceholder?: string`: The placeholder text for the search bar text input. Default `'Enter search text'`.
- `resultColumns?: number`: The number of columns to divide the search results into. Default: `3`.
- `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`.

#### Styling your Selector

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.

The images below will help you understand the nomenclature of the components:

![Diagram of component nomenclature for query form, suggestions, and footer](./docs/components_1.png)
![Diagram of component nomenclature for search results](./docs/components_2.png)

Here are all the props available for styling the component:

- `queryFormClassName?: string`: Additional `className` for the query form section of the component. You can find the default style applied in `src/components/QueryForm.css`.
- `queryFormInputClassName?: string`: Additional `className` for the text input in the query form. You can find the default style applied in `src/components/QueryForm.css`.
- `queryFormSubmitClassName?: string`: Additional `className` for the submit button in the query form. You can find the default style applied in `src/components/QueryForm.css`.
- `queryFormStyle?: object`: A style object to add to the query form style. You can find the default style applied in `src/components/QueryForm.css`.
- `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`.
- `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`.
- `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'`.
- `searchResultsClassName?: string`: Additional `className` for the search results component. You can find the default style in `src/components/SearchResults.css`.
- `searchResultsStyle?: object`: A style object to the add to the search results container. You can find the default style in `src/components/SearchResults.css`.
- `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`.
- `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`.
- `suggestionsClassName?: string`: Additional `className` to add to the suggestions container. You can find the default style in `src/components/Suggestions.css`.
- `suggestionsStyle?: object`: A style object to add to the suggestions container. You can find the default style in `src/components/Suggestions.css`.
- `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`.
- `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`.
- `loaderClassName?: string`: Additional `className` to add to the loader container. You can find the default style in `src/components/Selector.css`.
- `loaderStyle?: object`: A style object to add to the loader container. You can find the default style in `src/components/Selector.css`.
- `loaderContent?: string or Component`: You can pass in a `string` or customer component to display when results are loading. Default `'Loading'...`.
- `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`.
- `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`.
- `footerClassName?: string`: Additional `className` to add to footer of selector. You can find the default style in `src/components/Selector.css`.
- `footerStyle?: object`: A style object to add to footer of selector. You can find the default style in `src/components/Selector.css`.

If you have a cool style you'd like to share, please [make an issue](https://github.com/tshaddix/react-giphy-selector/issues).

### Rating

The `Rating` enum contains all the possible ratings you can limit searches to:

```js
Rating.Y
Rating.G
Rating.PG
Rating.PG13
Rating.R
```

### ResultSort

The `ResultSort` enum contains the different sort methods supported by the Giphy API.

```js
ResultSort.Recent // ordered by most recent
ResultSort.Relevant // ordered by relevance
```
Binary file added docs/components_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/components_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/example_1.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions example/example.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React Giphy Selector - Example</title>
</head>
<body>
<div id="example"></div>

<!-- Main -->
<script src="./bundle.js"></script>
</body>
</html>
39 changes: 39 additions & 0 deletions example/src/example.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
.customQueryFormSubmit {
background: #0097cf;
color: #fff;
border: 0;
padding: 10px 20px;
font-size: 16px;
font-weight: bold;
}

.customQueryFormInput {
padding-left: 10px;
padding-right: 10px;
border: 1px solid #e0e0e0;
border-right: 0;
box-shadow: none;
}

.customSearchResults {
max-height: 400px;
margin-top: 10px;
margin-bottom: 10px;
}

/********************************
CSS classes for example fake modal
********************************/

body {
background: #333;
font-family: sans-serif;
}

.modal {
max-width: 600px;
margin: 60px auto;
background: #fff;
padding: 20px;
border-bottom: 5px solid #111;
}
98 changes: 98 additions & 0 deletions example/src/example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { Selector, Rating } from "../../lib";
import * as React from "react";
import * as ReactDOM from "react-dom";

const customStyle = require("./example.css");

// feel free to change these :)
const suggestions = [
"watching",
"quiz",
"stop it",
"nice one",
"learning",
"reading",
"working"
];

interface IExampleProps {
suggestions: string[];
}

interface IExampleState {
apiKey: string;
isKeySubmitted: boolean;
}

class ExampleApp extends React.Component<IExampleProps, IExampleState> {
state: IExampleState;

constructor(props: IExampleProps) {
super(props);

this.state = {
apiKey: "",
isKeySubmitted: false
};

this.onKeyChange = this.onKeyChange.bind(this);
this.onKeySubmit = this.onKeySubmit.bind(this);
this.onGifSelected = this.onGifSelected.bind(this);
}

public onKeyChange(event: any): void {
this.setState({ apiKey: event.target.value });
}

public onKeySubmit(event: any): void {
event.preventDefault();

this.setState({
isKeySubmitted: true
});
}

public onGifSelected(gifObject: any): void {
alert(`You selected a gif! id: ${gifObject.id}`);
}

public render(): JSX.Element {
const { apiKey, isKeySubmitted } = this.state;
const { suggestions } = this.props;

if (!isKeySubmitted) {
return (
<form onSubmit={this.onKeySubmit}>
<input
type="text"
placeholder="Enter your Giphy API Key"
value={apiKey}
onChange={this.onKeyChange}
/>
<button type="submit">Set API Key</button>
</form>
);
}

return (
<div className={customStyle.modal}>
<Selector
apiKey={apiKey}
suggestions={suggestions}
onGifSelected={this.onGifSelected}
rating={Rating.G}
limit={40}
queryFormInputClassName={customStyle.customQueryFormInput}
queryFormSubmitClassName={customStyle.customQueryFormSubmit}
searchResultsClassName={customStyle.customSearchResults}
searchResultClassName={customStyle.customSearchResult}
/>
</div>
);
}
}

ReactDOM.render(
<ExampleApp suggestions={suggestions} />,
document.getElementById("example")
);
30 changes: 30 additions & 0 deletions example/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module.exports = {
entry: "./example/src/example.tsx",
output: {
filename: "bundle.js",
path: __dirname
},

// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",

resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: [".ts", ".tsx", ".js", ".json"]
},

module: {
rules: [
// All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
{ test: /\.tsx?$/, loader: "awesome-typescript-loader" },

// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" },

{
test: /\.css$/,
loader: ["style-loader", "css-loader?sourceMap&modules"]
}
]
}
};
2 changes: 2 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export {Rating, ResultSort, IGifImage, IGifObject} from './src/types';
export {Selector, ISelectorProps} from './src/components/Selector';
Loading

0 comments on commit ad26c34

Please sign in to comment.