From 95429e6cf390dfd24a2483ccb1108f1ae8c83007 Mon Sep 17 00:00:00 2001 From: Ronak Desai Date: Mon, 25 Jun 2018 20:59:13 -0400 Subject: [PATCH] feat(Dropdown): lazyLoad prop for menu items (#1918) * feat(Dropdown): lazy load options * test(Dropdown): update for lazy loaded options * feat(Dropdown): add lazyLoad prop * test(Dropdown): restore tests * fix(Dropdown): make lazyLoad optional --- src/modules/Dropdown/Dropdown.d.ts | 3 +++ src/modules/Dropdown/Dropdown.js | 11 ++++++++-- test/specs/modules/Dropdown/Dropdown-test.js | 23 +++++++++++++++----- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/modules/Dropdown/Dropdown.d.ts b/src/modules/Dropdown/Dropdown.d.ts index 690131ed27..e432a550a9 100644 --- a/src/modules/Dropdown/Dropdown.d.ts +++ b/src/modules/Dropdown/Dropdown.d.ts @@ -98,6 +98,9 @@ export interface DropdownProps { /** A dropdown can be labeled. */ labeled?: boolean + /** A dropdown can defer rendering its options until it is open. */ + lazyLoad?: boolean + /** A dropdown can show that it is currently loading data. */ loading?: boolean diff --git a/src/modules/Dropdown/Dropdown.js b/src/modules/Dropdown/Dropdown.js index 0d34b7f260..ac9c9d1e7c 100644 --- a/src/modules/Dropdown/Dropdown.js +++ b/src/modules/Dropdown/Dropdown.js @@ -142,6 +142,9 @@ export default class Dropdown extends Component { /** A dropdown can be labeled. */ labeled: PropTypes.bool, + /** A dropdown can defer rendering its options until it is open. */ + lazyLoad: PropTypes.bool, + /** A dropdown can show that it is currently loading data. */ loading: PropTypes.bool, @@ -1228,8 +1231,12 @@ export default class Dropdown extends Component { } renderOptions = () => { - const { multiple, search, noResultsMessage } = this.props - const { selectedIndex, value } = this.state + const { lazyLoad, multiple, search, noResultsMessage } = this.props + const { open, selectedIndex, value } = this.state + + // lazy load, only render options when open + if (lazyLoad && !open) return null + const options = this.getMenuOptions() if (noResultsMessage !== null && search && _.isEmpty(options)) { diff --git a/test/specs/modules/Dropdown/Dropdown-test.js b/test/specs/modules/Dropdown/Dropdown-test.js index 727a3347a4..05287af689 100644 --- a/test/specs/modules/Dropdown/Dropdown-test.js +++ b/test/specs/modules/Dropdown/Dropdown-test.js @@ -468,6 +468,7 @@ describe('Dropdown', () => { .first() .simulate('click') .should.have.prop('active', true) + wrapper.should.have.state('value', options[0].value) dropdownMenuIsClosed() @@ -914,11 +915,7 @@ describe('Dropdown', () => { wrapper .find('DropdownItem') .at(1) - .should.have.prop('selected', false) - wrapper - .find('DropdownItem') - .at(1) - .should.have.prop('active', false) + .should.have.props({ selected: false, active: false }) // select and make active domEvent.keyDown(document, { key: 'ArrowDown' }) @@ -928,7 +925,7 @@ describe('Dropdown', () => { wrapper .find('DropdownItem') .at(1) - .should.have.prop('active', true) + .should.have.props({ selected: true, active: true }) }) it('closes the menu', () => { wrapperMount().simulate('click') @@ -2140,6 +2137,20 @@ describe('Dropdown', () => { }) }) + describe('lazyLoad', () => { + it('does not render options when closed', () => { + wrapperShallow().should.not.have.descendants( + 'DropdownItem', + ) + }) + + it('renders options when open', () => { + wrapperShallow().should.have.descendants( + 'DropdownItem', + ) + }) + }) + describe('Dropdown.Menu child', () => { it('renders child passed', () => { wrapperShallow(