Skip to content

Commit

Permalink
Merge pull request #1293 from DanielHeath/add-async-no-results-text
Browse files Browse the repository at this point in the history
Allow users to specify noResultsText
  • Loading branch information
JedWatson committed Oct 11, 2016
2 parents 2c1cc8e + 37613de commit 75f3e90
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 3 deletions.
33 changes: 30 additions & 3 deletions src/Async.js
Expand Up @@ -8,7 +8,7 @@ const propTypes = {
children: React.PropTypes.func.isRequired, // Child function responsible for creating the inner Select component; (props: Object): PropTypes.element
ignoreAccents: React.PropTypes.bool, // strip diacritics when filtering; defaults to true
ignoreCase: React.PropTypes.bool, // perform case-insensitive filtering; defaults to true
loadingPlaceholder: React.PropTypes.oneOfType([ // replaces the placeholder while options are loading
loadingPlaceholder: React.PropTypes.oneOfType([ // replaces the placeholder while options are loading
React.PropTypes.string,
React.PropTypes.node
]),
Expand All @@ -18,11 +18,16 @@ const propTypes = {
React.PropTypes.string,
React.PropTypes.node
]),
noResultsText: React.PropTypes.oneOfType([ // field noResultsText, displayed when no options come back from the server
React.PropTypes.string,
React.PropTypes.node
]),
searchPromptText: React.PropTypes.oneOfType([ // label to prompt for search input
React.PropTypes.string,
React.PropTypes.node
]),
onInputChange: React.PropTypes.func, // optional for keeping track of what is being typed
value: React.PropTypes.any, // initial field value
};

const defaultProps = {
Expand Down Expand Up @@ -139,12 +144,34 @@ export default class Async extends Component {
return this.loadOptions(inputValue);
}

inputValue() {
if (this.select) {
return this.select.state.inputValue;
}
return '';
}

noResultsText() {
const { loadingPlaceholder, noResultsText, searchPromptText } = this.props;
const { isLoading } = this.state;

const inputValue = this.inputValue();

if (isLoading) {
return loadingPlaceholder;
}
if (inputValue && noResultsText) {
return noResultsText;
}
return searchPromptText;
}

render () {
const { children, loadingPlaceholder, placeholder, searchPromptText } = this.props;
const { children, loadingPlaceholder, placeholder } = this.props;
const { isLoading, options } = this.state;

const props = {
noResultsText: isLoading ? loadingPlaceholder : searchPromptText,
noResultsText: this.noResultsText(),
placeholder: isLoading ? loadingPlaceholder : placeholder,
options: isLoading ? [] : options,
ref: (ref) => (this.select = ref)
Expand Down
61 changes: 61 additions & 0 deletions test/Async-test.js
Expand Up @@ -333,6 +333,67 @@ describe('Async', () => {
});
});

describe('noResultsText', () => {

beforeEach(() => {
createControl({
searchPromptText: 'searchPromptText',
loadingPlaceholder: 'loadingPlaceholder',
noResultsText: 'noResultsText',
});
});

describe('before the user inputs text', () => {
it('returns the searchPromptText', () => {
expect(asyncInstance.noResultsText(), 'to equal', 'searchPromptText');
});
});

describe('while results are loading', () => {
beforeEach((cb) => {
asyncInstance.setState({
isLoading: true,
}, cb);
});
it('returns the loading indicator', () => {
asyncInstance.select = { state: { inputValue: 'asdf' } };
expect(asyncInstance.noResultsText(), 'to equal', 'loadingPlaceholder');
});
});

describe('after an empty result set loads', () => {
beforeEach((cb) => {
asyncInstance.setState({
isLoading: false,
}, cb);
});

describe('if noResultsText has been provided', () => {
it('returns the noResultsText', () => {
asyncInstance.select = { state: { inputValue: 'asdf' } };
expect(asyncInstance.noResultsText(), 'to equal', 'noResultsText');
});
});

describe('if noResultsText is empty', () => {
beforeEach((cb) => {
createControl({
searchPromptText: 'searchPromptText',
loadingPlaceholder: 'loadingPlaceholder'
});
asyncInstance.setState({
isLoading: false,
inputValue: 'asdfkljhadsf'
}, cb);
});
it('falls back to searchPromptText', () => {
asyncInstance.select = { state: { inputValue: 'asdf' } };
expect(asyncInstance.noResultsText(), 'to equal', 'searchPromptText');
});
});
});
});

describe('children function', () => {
it('should allow a custom select type to be rendered', () => {
let childProps;
Expand Down

0 comments on commit 75f3e90

Please sign in to comment.