From e8e258212b05244abce42143b11b8ecacbce8448 Mon Sep 17 00:00:00 2001 From: Flip Sasser Date: Wed, 21 Nov 2018 10:11:19 -0800 Subject: [PATCH 1/4] Allow users to opt-out of the wrapper component --- lib/Autocomplete.js | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/Autocomplete.js b/lib/Autocomplete.js index 1658c8bb..e07ca688 100644 --- a/lib/Autocomplete.js +++ b/lib/Autocomplete.js @@ -121,6 +121,10 @@ class Autocomplete extends React.Component { * placeholder, event handlers (onFocus, onBlur, etc.), autoFocus, etc.. */ inputProps: PropTypes.object, + /** + * Wrap the input and the dropdown menu in a div? Defaults to true + */ + wrapper: PropTypes.boolean, /** * Props that are applied to the element which wraps the `` and * dropdown menu elements rendered by `Autocomplete`. @@ -161,6 +165,7 @@ class Autocomplete extends React.Component { static defaultProps = { value: '', + wrapper: true, wrapperProps: {}, wrapperStyle: { display: 'inline-block' @@ -570,8 +575,8 @@ class Autocomplete extends React.Component { const { inputProps } = this.props const open = this.isOpen() - return ( -
+ const menu = ( + {this.props.renderInput({ ...inputProps, role: 'combobox', @@ -592,10 +597,22 @@ class Autocomplete extends React.Component { {JSON.stringify(this._debugStates.slice(Math.max(0, this._debugStates.length - 5), this._debugStates.length), null, 2)} )} -
+ ) + + if (this.props.wrapper) { + return ( +
+ {menu} +
+ ) + } else { + return menu + } } } module.exports = Autocomplete - From aa404393cd1e42b7c1cbf49220c26a20818e2002 Mon Sep 17 00:00:00 2001 From: Flip Sasser Date: Wed, 21 Nov 2018 10:53:10 -0800 Subject: [PATCH 2/4] Fix wrapper prop type (bool vs boolean, oops) --- lib/Autocomplete.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Autocomplete.js b/lib/Autocomplete.js index e07ca688..1cb26422 100644 --- a/lib/Autocomplete.js +++ b/lib/Autocomplete.js @@ -124,7 +124,7 @@ class Autocomplete extends React.Component { /** * Wrap the input and the dropdown menu in a div? Defaults to true */ - wrapper: PropTypes.boolean, + wrapper: PropTypes.bool, /** * Props that are applied to the element which wraps the `` and * dropdown menu elements rendered by `Autocomplete`. From 83def49d6c5084075b67f46b0a226708610bc64d Mon Sep 17 00:00:00 2001 From: Flip Sasser Date: Wed, 21 Nov 2018 11:05:08 -0800 Subject: [PATCH 3/4] Remove use of React.Fragment and instead return an array of Elements --- lib/Autocomplete.js | 55 +++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/lib/Autocomplete.js b/lib/Autocomplete.js index 1cb26422..b522d919 100644 --- a/lib/Autocomplete.js +++ b/lib/Autocomplete.js @@ -172,13 +172,13 @@ class Autocomplete extends React.Component { }, inputProps: {}, renderInput(props) { - return + return }, onChange() {}, onSelect() {}, isItemSelectable() { return true }, renderMenu(items, value, style) { - return
+ return
}, menuStyle: { borderRadius: '3px', @@ -480,6 +480,7 @@ class Autocomplete extends React.Component { } const menu = this.props.renderMenu(items, this.props.value, style) return React.cloneElement(menu, { + key: 'autocomplete:menu', ref: e => this.refs.menu = e, // Ignore blur to prevent menu from de-rendering before we can process click onTouchStart: () => this.setIgnoreBlur(true), @@ -575,30 +576,28 @@ class Autocomplete extends React.Component { const { inputProps } = this.props const open = this.isOpen() - const menu = ( - - {this.props.renderInput({ - ...inputProps, - role: 'combobox', - 'aria-autocomplete': 'list', - 'aria-expanded': open, - autoComplete: 'off', - ref: this.exposeAPI, - onFocus: this.handleInputFocus, - onBlur: this.handleInputBlur, - onChange: this.handleChange, - onKeyDown: this.composeEventHandlers(this.handleKeyDown, inputProps.onKeyDown), - onClick: this.composeEventHandlers(this.handleInputClick, inputProps.onClick), - value: this.props.value, - })} - {open && this.renderMenu()} - {this.props.debug && ( -
-            {JSON.stringify(this._debugStates.slice(Math.max(0, this._debugStates.length - 5), this._debugStates.length), null, 2)}
-          
- )} -
- ) + const input = this.props.renderInput({ + ...inputProps, + role: 'combobox', + 'aria-autocomplete': 'list', + 'aria-expanded': open, + autoComplete: 'off', + ref: this.exposeAPI, + onFocus: this.handleInputFocus, + onBlur: this.handleInputBlur, + onChange: this.handleChange, + onKeyDown: this.composeEventHandlers(this.handleKeyDown, inputProps.onKeyDown), + onClick: this.composeEventHandlers(this.handleInputClick, inputProps.onClick), + value: this.props.value, + }) + + const menu = open ? this.renderMenu() : null + + const debug = this.props.debug ? ( +
+        {JSON.stringify(this._debugStates.slice(Math.max(0, this._debugStates.length - 5), this._debugStates.length), null, 2)}
+      
+ ) : null if (this.props.wrapper) { return ( @@ -606,11 +605,13 @@ class Autocomplete extends React.Component { style={{ ...this.props.wrapperStyle }} {...this.props.wrapperProps} > + {input} {menu} + {debug}
) } else { - return menu + return [input, menu, debug] } } } From 897fbb3931bb9889fa2a6691018de2ccac038a5c Mon Sep 17 00:00:00 2001 From: Flip Sasser Date: Wed, 21 Nov 2018 11:10:10 -0800 Subject: [PATCH 4/4] Add clearer documentation --- README.md | 7 +++++++ lib/Autocomplete.js | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e78523da..09f312a6 100644 --- a/README.md +++ b/README.md @@ -190,6 +190,13 @@ Default value: `''` The value to display in the input field +#### `wrapper: Boolean` (optional) +Default value: `true` + +Whether or not to wrap the input and menu items in a `
` tag. Setting +this to `false` will render without a wrapper, discarding any overrides from +`wrapperProps` and `wrapperStyle`. + #### `wrapperProps: Object` (optional) Default value: `{}` diff --git a/lib/Autocomplete.js b/lib/Autocomplete.js index b522d919..86ce3323 100644 --- a/lib/Autocomplete.js +++ b/lib/Autocomplete.js @@ -122,7 +122,7 @@ class Autocomplete extends React.Component { */ inputProps: PropTypes.object, /** - * Wrap the input and the dropdown menu in a div? Defaults to true + * Whether or not to wrap the input and menu items in a div. */ wrapper: PropTypes.bool, /**