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 1658c8bb..86ce3323 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, + /** + * Whether or not to wrap the input and menu items in a div. + */ + wrapper: PropTypes.bool, /** * Props that are applied to the element which wraps the `` and * dropdown menu elements rendered by `Autocomplete`. @@ -161,19 +165,20 @@ class Autocomplete extends React.Component { static defaultProps = { value: '', + wrapper: true, wrapperProps: {}, wrapperStyle: { display: 'inline-block' }, inputProps: {}, renderInput(props) { - return + return }, onChange() {}, onSelect() {}, isItemSelectable() { return true }, renderMenu(items, value, style) { - return
+ return
}, menuStyle: { borderRadius: '3px', @@ -475,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), @@ -570,32 +576,44 @@ class Autocomplete extends React.Component { const { inputProps } = this.props const open = this.isOpen() - return ( -
- {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 ( +
+ {input} + {menu} + {debug} +
+ ) + } else { + return [input, menu, debug] + } } } module.exports = Autocomplete -