Skip to content
This repository has been archived by the owner on Oct 19, 2021. It is now read-only.

Commit

Permalink
feat(MultiSelect): add open prop (#1793)
Browse files Browse the repository at this point in the history
* feat(MultiSelect): add isOpen prop

* feat(MultiSelect): add state handling for open prop

* fix(MultiSelect): test update
  • Loading branch information
Nathan authored and asudoh committed Feb 25, 2019
1 parent 17e3041 commit f2b4be2
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 6 deletions.
21 changes: 20 additions & 1 deletion src/components/MultiSelect/FilterableMultiSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,26 @@ export default class FilterableMultiSelect extends React.Component {
* If invalid, what is the error?
*/
invalidText: PropTypes.string,

/**
* Initialize the component with an open(`true`)/closed(`false`) menu.
*/
open: PropTypes.bool,
};

static getDerivedStateFromProps({ open }, state) {
/**
* programmatically control this `open` prop
*/
const { prevOpen } = state;
return prevOpen === open
? null
: {
isOpen: open,
prevOpen: open,
};
}

static defaultProps = {
compareItems: defaultCompareItems,
disabled: false,
Expand All @@ -91,13 +109,14 @@ export default class FilterableMultiSelect extends React.Component {
locale: 'en',
sortItems: defaultSortItems,
light: false,
open: false,
};

constructor(props) {
super(props);
this.state = {
highlightedIndex: null,
isOpen: false,
isOpen: props.open,
inputValue: '',
};
}
Expand Down
21 changes: 20 additions & 1 deletion src/components/MultiSelect/MultiSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,30 @@ export default class MultiSelect extends React.Component {
*/
invalidText: PropTypes.string,

/**
* Initialize the component with an open(`true`)/closed(`false`) menu.
*/
open: PropTypes.bool,

/**
* Callback function for translating ListBoxMenuIcon SVG title
*/
translateWithId: PropTypes.func,
};

static getDerivedStateFromProps({ open }, state) {
/**
* programmatically control this `open` prop
*/
const { prevOpen } = state;
return prevOpen === open
? null
: {
isOpen: open,
prevOpen: open,
};
}

static defaultProps = {
compareItems: defaultCompareItems,
disabled: false,
Expand All @@ -108,13 +126,14 @@ export default class MultiSelect extends React.Component {
type: 'default',
light: false,
title: false,
open: false,
};

constructor(props) {
super(props);
this.state = {
highlightedIndex: null,
isOpen: false,
isOpen: props.open,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ describe('MultiSelect.Filterable', () => {
expect(wrapper.find(listItemName).length).toBe(mockProps.items.length);
});

it('should initially have the menu open when open prop is provided', () => {
const wrapper = mount(<MultiSelect.Filterable {...mockProps} open />);
expect(wrapper.state('isOpen')).toBe(true);
});

it('should let the user toggle the menu by the menu icon', () => {
const wrapper = mount(<MultiSelect.Filterable {...mockProps} />);
findMenuIconNode(wrapper).simulate('click');
Expand Down
14 changes: 10 additions & 4 deletions src/components/MultiSelect/__tests__/MultiSelect-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ describe('MultiSelect', () => {
expect(wrapper.state('isOpen')).toEqual(false);
});

it('should initialize with the menu open', () => {
const items = generateItems(5, generateGenericItem);
const wrapper = mount(<MultiSelect label="Field" items={items} open />);
expect(wrapper.state('isOpen')).toEqual(true);
});

describe('#handleOnToggleMenu', () => {
it('should toggle the boolean `isOpen` field', () => {
const items = generateItems(5, generateGenericItem);
Expand Down Expand Up @@ -226,17 +232,17 @@ describe('MultiSelect', () => {
const getHighlightedId = () =>
wrapper.find('.bx--list-box__menu-item--highlighted').prop('id');
simulateArrowDown();
expect(getHighlightedId()).toBe('downshift-12-item-0');
expect(getHighlightedId()).toBe('downshift-13-item-0');
simulateArrowDown();
expect(getHighlightedId()).toBe('downshift-12-item-1');
expect(getHighlightedId()).toBe('downshift-13-item-1');
// Simulate "wrap" behavior
simulateArrowDown();
simulateArrowDown();
simulateArrowDown();
simulateArrowDown();
expect(getHighlightedId()).toBe('downshift-12-item-0');
expect(getHighlightedId()).toBe('downshift-13-item-0');
simulateArrowUp();
expect(getHighlightedId()).toBe('downshift-12-item-4');
expect(getHighlightedId()).toBe('downshift-13-item-4');
});

it('should close the menu when a user clicks outside of the control', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ exports[`MultiSelect.Filterable should render 1`] = `
light={false}
locale="en"
onChange={[MockFunction]}
open={false}
placeholder="Placeholder..."
sortItems={[Function]}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ exports[`MultiSelect should render 1`] = `
label="Field"
light={false}
locale="en"
open={false}
sortItems={[Function]}
title={false}
type="default"
Expand Down

0 comments on commit f2b4be2

Please sign in to comment.