Skip to content

Commit

Permalink
Merge branch 'add-autocomplete-dropdown'
Browse files Browse the repository at this point in the history
  • Loading branch information
tbillington committed Oct 9, 2017
2 parents b31e768 + b2472a4 commit 6c7f5ac
Show file tree
Hide file tree
Showing 24 changed files with 797 additions and 25 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ import { Input } from "sajari-react/ui/text";
<Input values={values} pipeline={pipeline} />
```

## AutocompleteDropdown

`AutocompleteDropdown` is a text box which performs autocomplete as the user types and renders autocomplete suggestions in a list underneath.

![autocomplete-suggest](https://media.giphy.com/media/xT39DnBWdmrxJ1Xd1S/giphy.gif)

```javascript
import { AutocompleteDropdown } from "sajari-react/ui/text";

<AutocompleteDropdown values={values} pipeline={pipeline} />
```

## Handling results

A typical search result UI could includes a summary of the search, maybe with options to change spellings or search for alternatives, and a list of the paginated results. We include components for all of these pieces so it's easy to get started.
Expand Down
34 changes: 34 additions & 0 deletions examples/autocomplete-dropdown/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Example: Autocomplete Dropdown

This example contains a search box with autocomplete dropdown.

![autocomplete](https://media.giphy.com/media/3ohhwAFqL3rxdpy4dG/giphy.gif)

It has been created using the [Create React App](https://github.com/facebookincubator/create-react-app) tool to make development and deployment quick and easy.

## Requirements

**You’ll need to have Node >= 6 on your machine to develop + build prod assets for this example**. You can use [nvm](https://github.com/creationix/nvm#installation) to easily switch Node versions between different projects.

# Getting Started

To use this as a starting point for your own search interface, copy this entire directory into your own workspace.

## Development

This example comes with great dev tooling (courtousy of [Create React App](https://github.com/facebookincubator/create-react-app). To get up and running:

```shell
$ npm install # Install dependencies
$ npm run start # Start development server
```

Now open [localhost:3000](localhost:3000) to see the example running in development mode. Any changes you make to the code will be automatically synced to your browser.

## Build for production

To create a production-ready build of a completed application (with compressed assets etc):

```shell
$ npm build
```
19 changes: 19 additions & 0 deletions examples/autocomplete-dropdown/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "autocomplete-dropdown",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "15.6.1",
"react-dom": "15.6.1",
"sajari-react": "1.4.0"
},
"devDependencies": {
"react-scripts": "1.0.11"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
Binary file added examples/autocomplete-dropdown/public/favicon.ico
Binary file not shown.
30 changes: 30 additions & 0 deletions examples/autocomplete-dropdown/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Example: Autocomplete Dropdown</title>
<style>
html {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
background-color: #f7f7f7;
}

body {
margin: 20px;
line-height: 24px;
}

* {
box-sizing: border-box;
}
</style>
</head>

<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>

</html>
42 changes: 42 additions & 0 deletions examples/autocomplete-dropdown/src/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from "react";

import { Pipeline, Values } from "sajari-react/controllers";
import { Response, Results, Summary, Paginator } from "sajari-react/ui/results";
import { AutocompleteDropdown } from "sajari-react/ui/text";

import "sajari-react/ui/text/AutocompleteInput.css";
import "sajari-react/ui/text/AutocompleteDropdown.css";
import "sajari-react/ui/results/Results.css";
import "sajari-react/ui/results/Paginator.css";

const project = "sajariptyltd";
const collection = "sajari-com";
const autocompletePipeline = new Pipeline(project, collection, "autocomplete");
const autocompleteValues = new Values();

const websitePipeline = new Pipeline(project, collection, "website");
const websiteValues = new Values();

class App extends React.Component {
render() {
return (
<div className="search-app">
<AutocompleteDropdown
values={autocompleteValues}
pipeline={autocompletePipeline}
forceSearchValues={websiteValues}
forceSearchPipeline={websitePipeline}
numSuggestions={5}
placeholder="Type to search"
/>
<Response pipeline={websitePipeline}>
<Summary values={websiteValues} pipeline={websitePipeline} />
<Results pipeline={websitePipeline} />
<Paginator values={websiteValues} pipeline={websitePipeline} />
</Response>
</div>
);
}
}

export default App;
6 changes: 6 additions & 0 deletions examples/autocomplete-dropdown/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from "react";
import ReactDOM from "react-dom";

import App from "./App";

ReactDOM.render(<App />, document.getElementById("root"));
10 changes: 10 additions & 0 deletions src/ui/classnames.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Produces a css class string from a class name to boolean value object map.
* Only class names whose values evaluate to true will be included.
* @param {Object} classes
* @return {string}
*/
const classnames = classes =>
Object.keys(classes).filter(key => classes[key]).join(" ");

export default classnames;
8 changes: 8 additions & 0 deletions src/ui/classnames.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import classnames from "./classnames";

test("basic usage", () => {
const className = classnames({ foo: true, bar: false });

expect(className).toContain("foo");
expect(className).not.toContain("bar");
});
13 changes: 6 additions & 7 deletions src/ui/overlay/Overlay.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
}

.sj-overlay-search {
padding-left: 10px;
padding-right: 10px;
padding: 0px 30px;
}

.sj-overlay-close {
Expand All @@ -57,12 +56,12 @@
font-size: 12px;
}

@media (max-width: 845px) {
.sj-overlay-close {
right: 3%;
@media (max-width: 768px) {
.sj-overlay-search {
padding: 0px 10px;
}

.sj-overlay .sj-search-bar-input-common {
width: 70vw;
.sj-overlay .sj-search-holder-outer {
margin-right: 54px;
}
}
25 changes: 25 additions & 0 deletions src/ui/text/AutocompleteDropdown.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.sj-autocomplete-dropdown {
position: relative;
}

.sj-suggestions {
border: 1px solid #ddd;
cursor: pointer;
}

.sj-suggestion {
font-size: 18px;
padding: 8px 8px;
background-color: #fff;
color: #666;
}

.sj-suggestion strong {
font-weight: 600;
color: #333;
}

.sj-suggestion.sj-suggestion-selected,
.sj-suggestion:hover {
background-color: #ddd;
}
51 changes: 51 additions & 0 deletions src/ui/text/AutocompleteDropdown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from "react";

import AutocompleteDropdownBase from "./AutocompleteDropdownBase";

class AutocompleteDropdown extends AutocompleteDropdownBase {
/**
* propTypes
* @property {Values} values Values object.
* @property {Pipeline} pipeline Pipeline object.
* @property {Values} forceSearchValues Values to use for forced search.
* @property {Pipeline} forceSearchPipeline Pipeline to use for forced search.
* @property {string} placeholder Placeholder to use for the input element.
* @property {number} [maxSuggestions=5] Maximum number of suggestion to show.
* @property {string} [qParam="q"] Search parameter.
* @property {string} [qOverrideParam="q.override"] Search override parameter.
* @property {boolean} [autoFocus=false] Whether to focus the input element on creation.
*/
static get propTypes() {
return AutocompleteDropdownBase.propTypes;
}

handleForceSearch = () => {
const {
values,
pipeline,
forceSearchValues,
forceSearchPipeline
} = this.props;
return {
values: forceSearchValues || values,
pipeline: forceSearchPipeline || pipeline
};
};

render() {
return (
<AutocompleteDropdownBase
{...this.props}
onForceSearch={this.handleForceSearch}
/>
);
}
}

AutocompleteDropdown.defaultProps = {
qParam: "q",
qOverrideParam: "q.override",
maxSuggestions: 5
};

export default AutocompleteDropdown;
14 changes: 14 additions & 0 deletions src/ui/text/AutocompleteDropdown.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from "react";
import ReactDOM from "react-dom";
import { Pipeline, Values } from "../../controllers";
import { AutocompleteDropdown } from "./";

test("renders without crashing", () => {
const div = document.createElement("div");
const pipeline = new Pipeline("", "");
const values = new Values();
ReactDOM.render(
<AutocompleteDropdown pipeline={pipeline} values={values} />,
div
);
});
Loading

0 comments on commit 6c7f5ac

Please sign in to comment.