From a3b44d1f591083a261431d3da4ac7154b78c58d9 Mon Sep 17 00:00:00 2001 From: Rob Phoenix Date: Thu, 20 Jun 2019 16:58:17 +0100 Subject: [PATCH] Add closeOnSelect prop to SelectMenu (#588) * Add closeOnSelect prop to SelectMenu This change adds a prop that when true the select menu will close when an option has been selected. closes #456 * Add docs for SelectMenu closeOnSave --- docs/src/pages/components/select-menu.mdx | 6 ++++++ src/select-menu/src/OptionsList.js | 12 +++++++++++- src/select-menu/src/SelectMenu.js | 12 ++++++++++-- src/select-menu/src/SelectMenuContent.js | 9 ++++++++- src/select-menu/stories/index.stories.js | 13 +++++++++++++ 5 files changed, 48 insertions(+), 4 deletions(-) diff --git a/docs/src/pages/components/select-menu.mdx b/docs/src/pages/components/select-menu.mdx index d066ad840..501c48a8a 100644 --- a/docs/src/pages/components/select-menu.mdx +++ b/docs/src/pages/components/select-menu.mdx @@ -18,6 +18,12 @@ and uses `react-tiny-virtual-list` for the rendering of the virtualized list of The `SelectMenu` is unopinionated in how many items are selected in the list. Pass an array to the `selected` prop to select more items. +## Close on select + +The `SelectMenu` by default will stay open when an option is selected. +This can be configured so that the menu closes on selection. +This will not apply for Multiselect menus. + ## Options prop structure ```js static diff --git a/src/select-menu/src/OptionsList.js b/src/select-menu/src/OptionsList.js index 7779417b4..65d401e66 100644 --- a/src/select-menu/src/OptionsList.js +++ b/src/select-menu/src/OptionsList.js @@ -35,10 +35,17 @@ export default class OptionsList extends PureComponent { */ isMultiSelect: PropTypes.bool, + /** + * When true, menu closes on option selection. + */ + closeOnSelect: PropTypes.bool, + /** * This holds the values of the options */ - selected: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])), + selected: PropTypes.arrayOf( + PropTypes.oneOfType([PropTypes.string, PropTypes.number]) + ), onSelect: PropTypes.func, onDeselect: PropTypes.func, onFilterChange: PropTypes.func, @@ -201,6 +208,9 @@ export default class OptionsList extends PureComponent { handleSelect = item => { this.props.onSelect(item) + if (!this.props.isMultiSelect && this.props.closeOnSelect) { + this.props.close() + } } handleDeselect = item => { diff --git a/src/select-menu/src/SelectMenu.js b/src/select-menu/src/SelectMenu.js index 0c2a5bcdf..7cca355cf 100644 --- a/src/select-menu/src/SelectMenu.js +++ b/src/select-menu/src/SelectMenu.js @@ -105,7 +105,12 @@ export default class SelectMenu extends PureComponent { * Can be a function that returns a node, or a node itself, that is * rendered instead of the options list when there are no options. */ - emptyView: PropTypes.oneOfType([PropTypes.func, PropTypes.node]) + emptyView: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), + + /* + * When true, menu closes on option selection. + */ + closeOnSelect: PropTypes.bool } static defaultProps = { @@ -116,7 +121,8 @@ export default class SelectMenu extends PureComponent { position: Position.BOTTOM_LEFT, isMultiSelect: false, filterPlaceholder: 'Filter...', - filterIcon: 'search' + filterIcon: 'search', + closeOnSelect: false } getDetailView = (close, detailView) => { @@ -163,6 +169,7 @@ export default class SelectMenu extends PureComponent { emptyView, titleView, isMultiSelect, + closeOnSelect, ...props } = this.props @@ -196,6 +203,7 @@ export default class SelectMenu extends PureComponent { close={close} {...this.getDetailView(close, detailView)} {...this.getEmptyView(close, emptyView)} + closeOnSelect={closeOnSelect} /> )} {...props} diff --git a/src/select-menu/src/SelectMenuContent.js b/src/select-menu/src/SelectMenuContent.js index 54fd12cb5..14d0de407 100644 --- a/src/select-menu/src/SelectMenuContent.js +++ b/src/select-menu/src/SelectMenuContent.js @@ -46,6 +46,11 @@ export default class SelectMenuContent extends PureComponent { */ isMultiSelect: PropTypes.bool, + /* + * When true, menu closes on option selection. + */ + closeOnSelect: PropTypes.bool, + /** * Node that is placed in the header section, above the options. */ @@ -84,7 +89,8 @@ export default class SelectMenuContent extends PureComponent { titleView, detailView, emptyView, - isMultiSelect + isMultiSelect, + closeOnSelect } = this.props const headerHeight = 40 @@ -114,6 +120,7 @@ export default class SelectMenuContent extends PureComponent { options={options} isMultiSelect={isMultiSelect} close={close} + closeOnSelect={closeOnSelect} {...listProps} /> )} diff --git a/src/select-menu/stories/index.stories.js b/src/select-menu/stories/index.stories.js index 817200df3..a36dd38cc 100644 --- a/src/select-menu/stories/index.stories.js +++ b/src/select-menu/stories/index.stories.js @@ -28,6 +28,19 @@ storiesOf('select-menu', module).add('SelectMenu', () => ( )} + + {({ setState, state }) => ( + setState({ selected: item.value })} + closeOnSelect + > + + + )} + {({ setState, state }) => (