From 5e7a1e24d88c05851e1a4efeab233fb58527ae12 Mon Sep 17 00:00:00 2001 From: yp Date: Thu, 9 Nov 2017 17:15:38 +0100 Subject: [PATCH] feat: add the option `suppressRefError` to `getRootProps`. (#241) * Add the option `suppressRefError` to `getRootProps`. Fixes paypal/downshift#235. * Add myself as contributor. * Fix Markdown in README. * Add also 'test' as contribution. --- .all-contributorsrc | 11 ++++++ README.md | 33 ++++++++++------ src/__tests__/downshift.get-root-props.js | 47 +++++++++++++++++++++++ src/downshift.js | 11 +++++- 4 files changed, 89 insertions(+), 13 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3c15e2ae7..a30cf4146 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -371,6 +371,17 @@ "example" ] }, + { + "login": "yp", + "name": "yp", + "avatar_url": "https://avatars1.githubusercontent.com/u/275483?v=4", + "profile": "http://algolab.eu/pirola", + "contributions": [ + "bug", + "code", + "test" + ] + }, { "login": "ifyoumakeit", "name": "Dave Garwacke", diff --git a/README.md b/README.md index 4f553ac08..ef2871590 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ autocomplete/dropdown/select/combobox components

[![version][version-badge]][package] [![MIT License][license-badge]][LICENSE] -[![All Contributors](https://img.shields.io/badge/all_contributors-44-orange.svg?style=flat-square)](#contributors) +[![All Contributors](https://img.shields.io/badge/all_contributors-45-orange.svg?style=flat-square)](#contributors) [![PRs Welcome][prs-badge]][prs] [![Chat][chat-badge]][chat] [![Code of Conduct][coc-badge]][coc] @@ -186,7 +186,7 @@ compute the `inputValue`. > `function(prevItem: any, item: any)` | defaults to: `(prevItem, item) => (prevItem !== item)` -Used to determine if the new `selectedItem` has changed compared to the +Used to determine if the new `selectedItem` has changed compared to the previous `selectedItem` and properly update Downshift's internal state. ### getA11yStatusMessage @@ -273,7 +273,7 @@ but differ slightly. > `function(inputValue: string, stateAndHelpers: object)` | optional, no useful default -Called whenever the input value changes. Useful to use instead or in combination of `onStateChange` when `inputValue` is a controlled prop to [avoid issues with cursor positions](https://github.com/paypal/downshift/issues/217). +Called whenever the input value changes. Useful to use instead or in combination of `onStateChange` when `inputValue` is a controlled prop to [avoid issues with cursor positions](https://github.com/paypal/downshift/issues/217). - `inputValue`: The current value of the input - `stateAndHelpers`: This is the same thing your `children` prop @@ -407,7 +407,7 @@ being overridden (or overriding the props returned). For example: | `getInputProps` | `function({})` | returns the props you should apply to the `input` element that you render. | | `getItemProps` | `function({})` | returns the props you should apply to any menu item elements you render. | | `getLabelProps` | `function({})` | returns the props you should apply to the `label` element that you render. | -| `getRootProps` | `function({})` | returns the props you should apply to the root element that you render. It can be optional. | +| `getRootProps` | `function({},{})` | returns the props you should apply to the root element that you render. It can be optional. | #### `getRootProps` @@ -425,6 +425,17 @@ Required properties: and your composite component would forward like: `
` +If you're rendering a composite component, `Downshift` checks that +`getRootProps` is called and that `refKey` is a prop of the returned composite +component. +This is done to catch common causes of errors but, in some cases, the check +could fail even if the ref is correctly forwarded to the root DOM component. +In these cases, you can provide the object `{suppressRefError : true}` as the +second argument to `getRootProps` to completely bypass the check. +**Please use it with extreme care and only if you are absolutely sure that the +ref is correctly forwarded otherwise `Downshift` will unexpectedly fail.** +See issue paypal/downshift#235 for the discussion that lead to this. + #### `getInputProps` This method should be applied to the `input` you render. It is recommended that @@ -650,14 +661,14 @@ you'd prefer to use these out of the box solutions, then that's fine too: Thanks goes to these people ([emoji key][emojis]): -| [
Kent C. Dodds](https://kentcdodds.com)
[πŸ’»](https://github.com/paypal/downshift/commits?author=kentcdodds "Code") [πŸ“–](https://github.com/paypal/downshift/commits?author=kentcdodds "Documentation") [πŸš‡](#infra-kentcdodds "Infrastructure (Hosting, Build-Tools, etc)") [⚠️](https://github.com/paypal/downshift/commits?author=kentcdodds "Tests") | [
Ryan Florence](http://twitter.com/ryanflorence)
[πŸ€”](#ideas-ryanflorence "Ideas, Planning, & Feedback") | [
Jared Forsyth](http://jaredforsyth.com)
[πŸ€”](#ideas-jaredly "Ideas, Planning, & Feedback") [πŸ“–](https://github.com/paypal/downshift/commits?author=jaredly "Documentation") | [
Jack Moore](https://github.com/jtmthf)
[πŸ’‘](#example-jtmthf "Examples") | [
Travis Arnold](http://travisrayarnold.com)
[πŸ’»](https://github.com/paypal/downshift/commits?author=souporserious "Code") [πŸ“–](https://github.com/paypal/downshift/commits?author=souporserious "Documentation") | [
Marcy Sutton](http://marcysutton.com)
[πŸ›](https://github.com/paypal/downshift/issues?q=author%3Amarcysutton "Bug reports") [πŸ€”](#ideas-marcysutton "Ideas, Planning, & Feedback") | [
Jeremy Gayed](http://www.jeremygayed.com)
[πŸ’‘](#example-tizmagik "Examples") | +| [
Kent C. Dodds](https://kentcdodds.com)
[πŸ’»](https://github.com/paypal/downshift/commits?author=kentcdodds "Code") [πŸ“–](https://github.com/paypal/downshift/commits?author=kentcdodds "Documentation") [πŸš‡](#infra-kentcdodds "Infrastructure (Hosting, Build-Tools, etc)") [⚠️](https://github.com/paypal/downshift/commits?author=kentcdodds "Tests") | [
Ryan Florence](http://twitter.com/ryanflorence)
[πŸ€”](#ideas-ryanflorence "Ideas, Planning, & Feedback") | [
Jared Forsyth](http://jaredforsyth.com)
[πŸ€”](#ideas-jaredly "Ideas, Planning, & Feedback") [πŸ“–](https://github.com/paypal/downshift/commits?author=jaredly "Documentation") | [
Jack Moore](https://github.com/jtmthf)
[πŸ’‘](#example-jtmthf "Examples") | [
Travis Arnold](http://travisrayarnold.com)
[πŸ’»](https://github.com/paypal/downshift/commits?author=souporserious "Code") [πŸ“–](https://github.com/paypal/downshift/commits?author=souporserious "Documentation") | [
Marcy Sutton](http://marcysutton.com)
[πŸ›](https://github.com/paypal/downshift/issues?q=author%3Amarcysutton "Bug reports") [πŸ€”](#ideas-marcysutton "Ideas, Planning, & Feedback") | [
Jeremy Gayed](http://www.jeremygayed.com)
[πŸ’‘](#example-tizmagik "Examples") | | :---: | :---: | :---: | :---: | :---: | :---: | :---: | -| [
Haroen Viaene](https://haroen.me)
[πŸ’‘](#example-Haroenv "Examples") | [
monssef](https://github.com/rezof)
[πŸ’‘](#example-rezof "Examples") | [
Federico Zivolo](https://fezvrasta.github.io)
[πŸ“–](https://github.com/paypal/downshift/commits?author=FezVrasta "Documentation") | [
Divyendu Singh](https://divyendusingh.com)
[πŸ’‘](#example-divyenduz "Examples") [πŸ’»](https://github.com/paypal/downshift/commits?author=divyenduz "Code") [πŸ“–](https://github.com/paypal/downshift/commits?author=divyenduz "Documentation") [⚠️](https://github.com/paypal/downshift/commits?author=divyenduz "Tests") | [
Muhammad Salman](https://github.com/salmanmanekia)
[πŸ’»](https://github.com/paypal/downshift/commits?author=salmanmanekia "Code") | [
JoΓ£o Alberto](https://twitter.com/psicotropidev)
[πŸ’»](https://github.com/paypal/downshift/commits?author=psicotropicos "Code") | [
Bernard Lin](https://github.com/bernard-lin)
[πŸ’»](https://github.com/paypal/downshift/commits?author=bernard-lin "Code") [πŸ“–](https://github.com/paypal/downshift/commits?author=bernard-lin "Documentation") | -| [
Geoff Davis](https://geoffdavis.info)
[πŸ’‘](#example-geoffdavis92 "Examples") | [
Anup](https://github.com/reznord)
[πŸ“–](https://github.com/paypal/downshift/commits?author=reznord "Documentation") | [
Ferdinand Salis](http://ferdinandsalis.com)
[πŸ›](https://github.com/paypal/downshift/issues?q=author%3Aferdinandsalis "Bug reports") [πŸ’»](https://github.com/paypal/downshift/commits?author=ferdinandsalis "Code") | [
Kye Hohenberger](https://github.com/tkh44)
[πŸ›](https://github.com/paypal/downshift/issues?q=author%3Atkh44 "Bug reports") | [
Julien Goux](https://github.com/jgoux)
[πŸ›](https://github.com/paypal/downshift/issues?q=author%3Ajgoux "Bug reports") [πŸ’»](https://github.com/paypal/downshift/commits?author=jgoux "Code") [⚠️](https://github.com/paypal/downshift/commits?author=jgoux "Tests") | [
Joachim Seminck](https://github.com/jseminck)
[πŸ’»](https://github.com/paypal/downshift/commits?author=jseminck "Code") | [
Jesse Harlin](http://jesseharlin.net/)
[πŸ›](https://github.com/paypal/downshift/issues?q=author%3Athe-simian "Bug reports") [πŸ’‘](#example-the-simian "Examples") | -| [
Matt Parrish](https://github.com/pbomb)
[πŸ”§](#tool-pbomb "Tools") [πŸ‘€](#review-pbomb "Reviewed Pull Requests") | [
thom](http://thom.kr)
[πŸ’»](https://github.com/paypal/downshift/commits?author=thomhos "Code") | [
Vu Tran](http://twitter.com/tranvu)
[πŸ’»](https://github.com/paypal/downshift/commits?author=vutran "Code") | [
Codie Mullins](https://github.com/codiemullins)
[πŸ’»](https://github.com/paypal/downshift/commits?author=codiemullins "Code") [πŸ’‘](#example-codiemullins "Examples") | [
Mohammad Rajabifard](https://morajabi.me)
[πŸ“–](https://github.com/paypal/downshift/commits?author=morajabi "Documentation") [πŸ€”](#ideas-morajabi "Ideas, Planning, & Feedback") | [
Frank Tan](https://github.com/tansongyang)
[πŸ’»](https://github.com/paypal/downshift/commits?author=tansongyang "Code") | [
Kier Borromeo](https://kierb.com)
[πŸ’‘](#example-srph "Examples") | -| [
Paul Veevers](https://github.com/paul-veevers)
[πŸ’»](https://github.com/paypal/downshift/commits?author=paul-veevers "Code") | [
Ron Cruz](https://github.com/Ronolibert)
[πŸ“–](https://github.com/paypal/downshift/commits?author=Ronolibert "Documentation") | [
Rick McGavin](http://rickmcgavin.github.io)
[πŸ“–](https://github.com/paypal/downshift/commits?author=rickMcGavin "Documentation") | [
Jelle Versele](http://twitter.com/vejersele)
[πŸ’‘](#example-vejersele "Examples") | [
Brent Ertz](https://github.com/brentertz)
[πŸ€”](#ideas-brentertz "Ideas, Planning, & Feedback") | [
Justice Mba ](https://github.com/Dajust)
[πŸ’»](https://github.com/paypal/downshift/commits?author=Dajust "Code") [πŸ“–](https://github.com/paypal/downshift/commits?author=Dajust "Documentation") [πŸ€”](#ideas-Dajust "Ideas, Planning, & Feedback") | [
Mark Ellis](http://mfellis.com)
[πŸ€”](#ideas-ellismarkf "Ideas, Planning, & Feedback") | -| [
us͑an̸df͘rien͜ds͠](http://ronak.io/)
[πŸ›](https://github.com/paypal/downshift/issues?q=author%3Ausandfriends "Bug reports") [πŸ’»](https://github.com/paypal/downshift/commits?author=usandfriends "Code") [⚠️](https://github.com/paypal/downshift/commits?author=usandfriends "Tests") | [
Robin Drexler](https://www.robin-drexler.com/)
[πŸ›](https://github.com/paypal/downshift/issues?q=author%3Arobin-drexler "Bug reports") [πŸ’»](https://github.com/paypal/downshift/commits?author=robin-drexler "Code") | [
Arturo Romero](http://arturoromero.info/)
[πŸ’‘](#example-arturoromeroslc "Examples") | [
Dave Garwacke](http://www.warbyparker.com)
[πŸ“–](https://github.com/paypal/downshift/commits?author=ifyoumakeit "Documentation") | [
Ivan Pazhitnykh](http://linkedin.com/in/drapegnik)
[πŸ’»](https://github.com/paypal/downshift/commits?author=Drapegnik "Code") [⚠️](https://github.com/paypal/downshift/commits?author=Drapegnik "Tests") | [
Luis Merino](https://github.com/Rendez)
[πŸ“–](https://github.com/paypal/downshift/commits?author=Rendez "Documentation") | [
Andrew Hansen](http://twitter.com/arahansen)
[πŸ’»](https://github.com/paypal/downshift/commits?author=arahansen "Code") [⚠️](https://github.com/paypal/downshift/commits?author=arahansen "Tests") | -| [
John Whiles](http://www.johnwhiles.com)
[πŸ’»](https://github.com/paypal/downshift/commits?author=Jwhiles "Code") | [
Justin Hall](https://github.com/wKovacs64)
[πŸš‡](#infra-wKovacs64 "Infrastructure (Hosting, Build-Tools, etc)") | +| [
Haroen Viaene](https://haroen.me)
[πŸ’‘](#example-Haroenv "Examples") | [
monssef](https://github.com/rezof)
[πŸ’‘](#example-rezof "Examples") | [
Federico Zivolo](https://fezvrasta.github.io)
[πŸ“–](https://github.com/paypal/downshift/commits?author=FezVrasta "Documentation") | [
Divyendu Singh](https://divyendusingh.com)
[πŸ’‘](#example-divyenduz "Examples") [πŸ’»](https://github.com/paypal/downshift/commits?author=divyenduz "Code") [πŸ“–](https://github.com/paypal/downshift/commits?author=divyenduz "Documentation") [⚠️](https://github.com/paypal/downshift/commits?author=divyenduz "Tests") | [
Muhammad Salman](https://github.com/salmanmanekia)
[πŸ’»](https://github.com/paypal/downshift/commits?author=salmanmanekia "Code") | [
JoΓ£o Alberto](https://twitter.com/psicotropidev)
[πŸ’»](https://github.com/paypal/downshift/commits?author=psicotropicos "Code") | [
Bernard Lin](https://github.com/bernard-lin)
[πŸ’»](https://github.com/paypal/downshift/commits?author=bernard-lin "Code") [πŸ“–](https://github.com/paypal/downshift/commits?author=bernard-lin "Documentation") | +| [
Geoff Davis](https://geoffdavis.info)
[πŸ’‘](#example-geoffdavis92 "Examples") | [
Anup](https://github.com/reznord)
[πŸ“–](https://github.com/paypal/downshift/commits?author=reznord "Documentation") | [
Ferdinand Salis](http://ferdinandsalis.com)
[πŸ›](https://github.com/paypal/downshift/issues?q=author%3Aferdinandsalis "Bug reports") [πŸ’»](https://github.com/paypal/downshift/commits?author=ferdinandsalis "Code") | [
Kye Hohenberger](https://github.com/tkh44)
[πŸ›](https://github.com/paypal/downshift/issues?q=author%3Atkh44 "Bug reports") | [
Julien Goux](https://github.com/jgoux)
[πŸ›](https://github.com/paypal/downshift/issues?q=author%3Ajgoux "Bug reports") [πŸ’»](https://github.com/paypal/downshift/commits?author=jgoux "Code") [⚠️](https://github.com/paypal/downshift/commits?author=jgoux "Tests") | [
Joachim Seminck](https://github.com/jseminck)
[πŸ’»](https://github.com/paypal/downshift/commits?author=jseminck "Code") | [
Jesse Harlin](http://jesseharlin.net/)
[πŸ›](https://github.com/paypal/downshift/issues?q=author%3Athe-simian "Bug reports") [πŸ’‘](#example-the-simian "Examples") | +| [
Matt Parrish](https://github.com/pbomb)
[πŸ”§](#tool-pbomb "Tools") [πŸ‘€](#review-pbomb "Reviewed Pull Requests") | [
thom](http://thom.kr)
[πŸ’»](https://github.com/paypal/downshift/commits?author=thomhos "Code") | [
Vu Tran](http://twitter.com/tranvu)
[πŸ’»](https://github.com/paypal/downshift/commits?author=vutran "Code") | [
Codie Mullins](https://github.com/codiemullins)
[πŸ’»](https://github.com/paypal/downshift/commits?author=codiemullins "Code") [πŸ’‘](#example-codiemullins "Examples") | [
Mohammad Rajabifard](https://morajabi.me)
[πŸ“–](https://github.com/paypal/downshift/commits?author=morajabi "Documentation") [πŸ€”](#ideas-morajabi "Ideas, Planning, & Feedback") | [
Frank Tan](https://github.com/tansongyang)
[πŸ’»](https://github.com/paypal/downshift/commits?author=tansongyang "Code") | [
Kier Borromeo](https://kierb.com)
[πŸ’‘](#example-srph "Examples") | +| [
Paul Veevers](https://github.com/paul-veevers)
[πŸ’»](https://github.com/paypal/downshift/commits?author=paul-veevers "Code") | [
Ron Cruz](https://github.com/Ronolibert)
[πŸ“–](https://github.com/paypal/downshift/commits?author=Ronolibert "Documentation") | [
Rick McGavin](http://rickmcgavin.github.io)
[πŸ“–](https://github.com/paypal/downshift/commits?author=rickMcGavin "Documentation") | [
Jelle Versele](http://twitter.com/vejersele)
[πŸ’‘](#example-vejersele "Examples") | [
Brent Ertz](https://github.com/brentertz)
[πŸ€”](#ideas-brentertz "Ideas, Planning, & Feedback") | [
Justice Mba ](https://github.com/Dajust)
[πŸ’»](https://github.com/paypal/downshift/commits?author=Dajust "Code") [πŸ“–](https://github.com/paypal/downshift/commits?author=Dajust "Documentation") [πŸ€”](#ideas-Dajust "Ideas, Planning, & Feedback") | [
Mark Ellis](http://mfellis.com)
[πŸ€”](#ideas-ellismarkf "Ideas, Planning, & Feedback") | +| [
us͑an̸df͘rien͜ds͠](http://ronak.io/)
[πŸ›](https://github.com/paypal/downshift/issues?q=author%3Ausandfriends "Bug reports") [πŸ’»](https://github.com/paypal/downshift/commits?author=usandfriends "Code") [⚠️](https://github.com/paypal/downshift/commits?author=usandfriends "Tests") | [
Robin Drexler](https://www.robin-drexler.com/)
[πŸ›](https://github.com/paypal/downshift/issues?q=author%3Arobin-drexler "Bug reports") [πŸ’»](https://github.com/paypal/downshift/commits?author=robin-drexler "Code") | [
Arturo Romero](http://arturoromero.info/)
[πŸ’‘](#example-arturoromeroslc "Examples") | [
yp](http://algolab.eu/pirola)
[πŸ›](https://github.com/paypal/downshift/issues?q=author%3Ayp "Bug reports") [πŸ’»](https://github.com/paypal/downshift/commits?author=yp "Code") [⚠️](https://github.com/paypal/downshift/commits?author=yp "Tests") | [
Dave Garwacke](http://www.warbyparker.com)
[πŸ“–](https://github.com/paypal/downshift/commits?author=ifyoumakeit "Documentation") | [
Ivan Pazhitnykh](http://linkedin.com/in/drapegnik)
[πŸ’»](https://github.com/paypal/downshift/commits?author=Drapegnik "Code") [⚠️](https://github.com/paypal/downshift/commits?author=Drapegnik "Tests") | [
Luis Merino](https://github.com/Rendez)
[πŸ“–](https://github.com/paypal/downshift/commits?author=Rendez "Documentation") | +| [
Andrew Hansen](http://twitter.com/arahansen)
[πŸ’»](https://github.com/paypal/downshift/commits?author=arahansen "Code") [⚠️](https://github.com/paypal/downshift/commits?author=arahansen "Tests") | [
John Whiles](http://www.johnwhiles.com)
[πŸ’»](https://github.com/paypal/downshift/commits?author=Jwhiles "Code") | [
Justin Hall](https://github.com/wKovacs64)
[πŸš‡](#infra-wKovacs64 "Infrastructure (Hosting, Build-Tools, etc)") | This project follows the [all-contributors][all-contributors] specification. diff --git a/src/__tests__/downshift.get-root-props.js b/src/__tests__/downshift.get-root-props.js index 061bca090..4f1c5495a 100644 --- a/src/__tests__/downshift.get-root-props.js +++ b/src/__tests__/downshift.get-root-props.js @@ -66,4 +66,51 @@ test('renders fine when rendering a composite component and applying getRootProp expect(() => mount()).not.toThrow() }) +test('returning a composite component and calling getRootProps without a refKey does not result in an error if suppressRefError is true', () => { + const MyComponent = () => ( + + {({getRootProps}) => ( + + )} + + ) + expect(() => mount()).not.toThrow() +}) + +test('returning a DOM element and calling getRootProps with a refKey does not result in an error if suppressRefError is true', () => { + const MyComponent = () => ( + + {({getRootProps}) => ( +
+ )} + + ) + expect(() => mount()).not.toThrow() +}) + +test('not applying the ref prop results in an error does not result in an error if suppressRefError is true', () => { + const MyComponent = () => ( + + {({getRootProps}) => { + const {onClick} = getRootProps({}, {suppressRefError: true}) + return
+ }} + + ) + expect(() => mount()).not.toThrow() +}) + +test('renders fine when rendering a composite component and applying getRootProps properly even if suppressRefError is true', () => { + const MyComponent = () => ( + + {({getRootProps}) => ( + + )} + + ) + expect(() => mount()).not.toThrow() +}) + /* eslint no-console:0 */ diff --git a/src/downshift.js b/src/downshift.js index 5921134a1..18444a181 100644 --- a/src/downshift.js +++ b/src/downshift.js @@ -426,11 +426,15 @@ class Downshift extends Component { rootRef = node => (this._rootNode = node) - getRootProps = ({refKey = 'ref', ...rest} = {}) => { + getRootProps = ( + {refKey = 'ref', ...rest} = {}, + {suppressRefError = false} = {}, + ) => { // this is used in the render to know whether the user has called getRootProps. // It uses that to know whether to apply the props automatically this.getRootProps.called = true this.getRootProps.refKey = refKey + this.getRootProps.suppressRefError = suppressRefError return { [refKey]: this.rootRef, ...rest, @@ -772,6 +776,7 @@ class Downshift extends Component { // apply the props for them. this.getRootProps.called = false this.getRootProps.refKey = undefined + this.getRootProps.suppressRefError = undefined // we do something similar for getLabelProps this.getLabelProps.called = false // and something similar for getInputProps @@ -781,7 +786,9 @@ class Downshift extends Component { return null } if (this.getRootProps.called) { - validateGetRootPropsCalledCorrectly(element, this.getRootProps) + if (!this.getRootProps.suppressRefError) { + validateGetRootPropsCalledCorrectly(element, this.getRootProps) + } return element } else if (isDOMElement(element)) { // they didn't apply the root props, but we can clone