Skip to content

Commit

Permalink
Add renderSuggestionsContainer prop
Browse files Browse the repository at this point in the history
  • Loading branch information
moroshko committed Aug 11, 2016
1 parent fcbbcbb commit 1cf060c
Show file tree
Hide file tree
Showing 14 changed files with 177 additions and 83 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
"react/jsx-uses-vars": 2,
"react/jsx-wrap-multilines": 2,

"mocha/no-exclusive-tests": "error"
"mocha/no-exclusive-tests": "error",
"mocha/no-skipped-tests": "error"
}
}
37 changes: 33 additions & 4 deletions FAQ.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,41 @@
### How do I get the input field?
<a name="gettingTheInputElement"></a>
### How do I get the input element?

The input field is available on the Autosuggest instance as `input`.
The input element is available on the Autosuggest instance as `input`.

For example, you could store the input field like this:
You could store the input element like this:

```js
<Autosuggest ref={autosuggest => this.input = autosuggest.input} ... />
function storeInputReference(autosuggest) {
if (autosuggest !== null) {
this.input = autosuggest.input;
}
}

<Autosuggest ref={storeInputReference} ... />
```

[Codepen example](http://codepen.io/moroshko/pen/WryOMP)

<a name="limitSuggestionsContainerScrolling"></a>
### How do I limit the scrolling of the suggestions container to the container itself?

When the suggestions container has a scroll bar, and you scroll beyond the start/end of the container, the page starts scrolling. To stop that, you can use [`react-isolated-scroll`](https://github.com/markdalgleish/react-isolated-scroll):

```js
import IsolatedScroll from 'react-isolated-scroll';

function renderSuggestionsContainer({ ref, ...rest }) {
const callRef = isolatedScroll => {
if (isolatedScroll !== null) {
ref(isolatedScroll.component);
}
};

return (
<IsolatedScroll {...rest} ref={callRef} />
);
}

<Autosuggest renderSuggestionsContainer={renderSuggestionsContainer} ... />
```
69 changes: 59 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ class Example extends React.Component {
* [`onSuggestionsUpdateRequested`](#onSuggestionsUpdateRequestedProp)
* [`getSuggestionValue`](#getSuggestionValueProp)
* [`renderSuggestion`](#renderSuggestionProp)
* [`renderSuggestionsContainer`](#renderSuggestionsContainerProp)
* [`inputProps`](#inputPropsProp)
* [`shouldRenderSuggestions`](#shouldRenderSuggestionsProp)
* [`alwaysRenderSuggestions`](#alwaysRenderSuggestionsProp)
Expand Down Expand Up @@ -284,6 +285,54 @@ function renderSuggestion(suggestion) {

**Note:** `renderSuggestion` must be a pure function (we optimize rendering performance based on this assumption).

<a name="renderSuggestionsContainerProp"></a>
#### renderSuggestionsContainer (optional)

You shouldn't use this function unless you want to customize the behaviour of the suggestions container. For example, you might want to add a custom text before/after the suggestions list, or [customize the scrolling behaviour of the suggestions container](https://github.com/moroshko/react-autosuggest/blob/master/FAQ.md#limitSuggestionsContainerScrolling).

`renderSuggestionsContainer` has the following signature:

```js
function renderSuggestionsContainer(props)
```

You should pass all the `props` to the topmost element that is returned from `renderSuggestionsContainer` with the following exceptions:

* `children` - these are the suggestions themselves. It's up to you where to render them.
* `ref` - when `renderSuggestionsContainer` returns a composite component (e.g. `<IsolatedScroll ... />` as opposed to a DOM node like `<div ... />`), you should call `ref` with the topmost element that the composite component renders.

Examples:

```js
function renderSuggestionsContainer({ children, ...rest }) {
return (
<div {...rest}>
<p>
Some text
</p>
{children}
</div>
);
}
```


```js
import IsolatedScroll from 'react-isolated-scroll';

function renderSuggestionsContainer({ ref, ...rest }) {
const callRef = isolatedScroll => {
if (isolatedScroll !== null) {
ref(isolatedScroll.component);
}
};

return (
<IsolatedScroll {...rest} ref={callRef} />
);
}
```

<a name="inputPropsProp"></a>
#### inputProps (required)

Expand Down Expand Up @@ -334,7 +383,7 @@ function shouldRenderSuggestions(value) {
}
```

When `shouldRenderSuggestions` returns `true`, **suggestions will be rendered only when the input field is focused**.
When `shouldRenderSuggestions` returns `true`, **suggestions will be rendered only when the input field is focused**.

If you would like to render suggestions regardless of whether the input field is focused or not, set `alwaysRenderSuggestions={true}` (`shouldRenderSuggestions` is ignored in this case).

Expand Down Expand Up @@ -463,15 +512,15 @@ When not specified, `theme` defaults to:

```js
{
container: 'react-autosuggest__container',
containerOpen: 'react-autosuggest__container--open',
input: 'react-autosuggest__input',
suggestionsContainer: 'react-autosuggest__suggestions-container',
suggestion: 'react-autosuggest__suggestion',
suggestionFocused: 'react-autosuggest__suggestion--focused',
sectionContainer: 'react-autosuggest__section-container',
sectionTitle: 'react-autosuggest__section-title',
sectionSuggestionsContainer: 'react-autosuggest__section-suggestions-container'
container: 'react-autosuggest__container',
containerOpen: 'react-autosuggest__container--open',
input: 'react-autosuggest__input',
suggestionsContainer: 'react-autosuggest__suggestions-container',
suggestionsList: 'react-autosuggest__suggestions-list',
suggestion: 'react-autosuggest__suggestion',
suggestionFocused: 'react-autosuggest__suggestion--focused',
sectionContainer: 'react-autosuggest__section-container',
sectionTitle: 'react-autosuggest__section-title'
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@
}

.react-autosuggest__suggestions-container {
display: none;
}

.react-autosuggest__container--open .react-autosuggest__suggestions-container {
display: block;
position: absolute;
top: 51px;
width: 280px;
margin: 0;
padding: 0;
list-style-type: none;
border: 1px solid #aaa;
background-color: #fff;
font-family: 'Open Sans', sans-serif;
Expand All @@ -39,6 +41,12 @@
z-index: 2;
}

.react-autosuggest__suggestions-list {
margin: 0;
padding: 0;
list-style-type: none;
}

.react-autosuggest__suggestion {
cursor: pointer;
padding: 10px 20px;
Expand All @@ -58,9 +66,3 @@
.react-autosuggest__section-container:first-child .react-autosuggest__section-title {
border-top: 0;
}

.react-autosuggest__section-suggestions-container {
margin: 0;
padding: 0;
list-style-type: none;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,28 @@
}

.suggestionsContainer {
position: absolute;
top: 51px;
width: 280px;
display: none;

.containerOpen & {
display: block;
position: absolute;
top: 51px;
width: 280px;
border: 1px solid @border-color;
background-color: #fff;
font-family: 'Open Sans', sans-serif;
font-weight: 300;
font-size: 20px;
border-bottom-left-radius: @border-radius;
border-bottom-right-radius: @border-radius;
z-index: 2;
}
}

.suggestionsList {
margin: 0;
padding: 0;
list-style-type: none;
border: 1px solid @border-color;
background-color: #fff;
font-family: 'Open Sans', sans-serif;
font-weight: 300;
font-size: 20px;
border-bottom-left-radius: @border-radius;
border-bottom-right-radius: @border-radius;
z-index: 2;
}

.suggestion {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,28 @@
}

.suggestionsContainer {
position: absolute;
top: 51px;
width: 280px;
display: none;

.containerOpen & {
display: block;
position: absolute;
top: 51px;
width: 280px;
border: 1px solid @border-color;
background-color: #fff;
font-family: 'Open Sans', sans-serif;
font-weight: 300;
font-size: @font-size;
border-bottom-left-radius: @border-radius;
border-bottom-right-radius: @border-radius;
z-index: 2;
}
}

.suggestionsList {
margin: 0;
padding: 0;
list-style-type: none;
border: 1px solid @border-color;
background-color: #fff;
font-family: 'Open Sans', sans-serif;
font-weight: 300;
font-size: @font-size;
border-bottom-left-radius: @border-radius;
border-bottom-right-radius: @border-radius;
z-index: 2;
}

.suggestion {
Expand All @@ -62,9 +70,3 @@
border-top: 0;
}
}

.sectionSuggestionsContainer {
margin: 0;
padding: 0;
list-style-type: none;
}
2 changes: 1 addition & 1 deletion demo/src/components/App/components/Header/redux.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import fetch from 'isomorphic-fetch';
const UPDATE_STARGAZERS = 'UPDATE_STARGAZERS';

const initialState = {
stargazers: '1053'
stargazers: '1061'
};

export function loadStargazers() {
Expand Down
14 changes: 11 additions & 3 deletions demo/standalone/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@
}

.react-autosuggest__suggestions-container {
display: none;
}

.react-autosuggest__container--open .react-autosuggest__suggestions-container {
display: block;
position: relative;
top: -1px;
width: 280px;
margin: 0;
padding: 0;
list-style-type: none;
border: 1px solid #aaa;
background-color: #fff;
font-family: 'Open Sans', sans-serif;
Expand All @@ -39,6 +41,12 @@
z-index: 2;
}

.react-autosuggest__suggestions-list {
margin: 0;
padding: 0;
list-style-type: none;
}

.react-autosuggest__suggestion {
cursor: pointer;
padding: 10px 20px;
Expand Down
Binary file modified dom-structure.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"prepublish": "npm run dist && npm run standalone"
},
"dependencies": {
"react-autowhatever": "^4.3.0",
"react-autowhatever": "^5.1.2",
"react-redux": "^4.4.5",
"redux": "^3.5.1"
},
Expand All @@ -45,9 +45,9 @@
"chai": "^3.5.0",
"css-loader": "^0.23.1",
"es6-promise": "^3.1.2",
"eslint": "3.2.0",
"eslint": "^3.2.2",
"eslint-plugin-mocha": "^4.3.0",
"eslint-plugin-react": "^6.0.0-rc.0",
"eslint-plugin-react": "^6.0.0",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.8.5",
"happypack": "^2.0.4",
Expand Down
8 changes: 5 additions & 3 deletions src/Autosuggest.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ function mapStateToProps(state) {
class Autosuggest extends Component {
static propTypes = {
suggestions: PropTypes.array.isRequired,
renderSuggestionsContainer: PropTypes.func,
onSuggestionsUpdateRequested: PropTypes.func.isRequired,
getSuggestionValue: PropTypes.func.isRequired,
renderSuggestion: PropTypes.func.isRequired,
Expand Down Expand Up @@ -228,9 +229,9 @@ class Autosuggest extends Component {

render() {
const {
suggestions, renderSuggestion, inputProps, shouldRenderSuggestions,
onSuggestionSelected, multiSection, renderSectionTitle, id,
getSectionSuggestions, theme, isFocused, isCollapsed, focusedSectionIndex,
suggestions, renderSuggestionsContainer, renderSuggestion, inputProps,
shouldRenderSuggestions, onSuggestionSelected, multiSection, renderSectionTitle,
id, getSectionSuggestions, theme, isFocused, isCollapsed, focusedSectionIndex,
focusedSuggestionIndex, valueBeforeUpDown, inputFocused, inputBlurred,
inputChanged, updateFocusedSuggestion, revealSuggestions, closeSuggestions,
getSuggestionValue, alwaysRenderSuggestions
Expand Down Expand Up @@ -359,6 +360,7 @@ class Autosuggest extends Component {
<Autowhatever
multiSection={multiSection}
items={items}
renderItemsContainer={renderSuggestionsContainer}
renderItem={renderSuggestion}
renderItemData={renderSuggestionData}
renderSectionTitle={renderSectionTitle}
Expand Down
Loading

0 comments on commit 1cf060c

Please sign in to comment.