forked from reactstrap/reactstrap
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(UncontrolledCollapse): add UncontrolledCollapse (reactstrap#1009)
- Loading branch information
1 parent
459df03
commit 355d2b8
Showing
8 changed files
with
268 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React from 'react'; | ||
import { UncontrolledCollapse, Button, CardBody, Card } from 'reactstrap'; | ||
|
||
const Example = () => ( | ||
<div> | ||
<Button color="primary" id="toggler" style={{ marginBottom: '1rem' }}> | ||
Toggle | ||
</Button> | ||
<UncontrolledCollapse toggler="#toggler"> | ||
<Card> | ||
<CardBody> | ||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nesciunt magni, voluptas debitis | ||
similique porro a molestias consequuntur earum odio officiis natus, amet hic, iste sed | ||
dignissimos esse fuga! Minus, alias. | ||
</CardBody> | ||
</Card> | ||
</UncontrolledCollapse> | ||
</div> | ||
); | ||
|
||
export default Example; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,8 +14,10 @@ | |
"report-coverage": "coveralls < ./coverage/lcov.info", | ||
"test": "cross-env BABEL_ENV=test react-scripts test --env=jsdom", | ||
"cover": "npm test -- --coverage", | ||
"start": "cross-env BABEL_ENV=webpack webpack-dev-server --config ./webpack.dev.config.js --watch", | ||
"build-docs": "cross-env BABEL_ENV=webpack WEBPACK_BUILD=production webpack --config ./webpack.dev.config.js --progress --colors", | ||
"start": | ||
"cross-env BABEL_ENV=webpack webpack-dev-server --config ./webpack.dev.config.js --watch", | ||
"build-docs": | ||
"cross-env BABEL_ENV=webpack WEBPACK_BUILD=production webpack --config ./webpack.dev.config.js --progress --colors", | ||
"build": "rollup -c", | ||
"prebuild": "cross-env BABEL_ENV=lib-dir babel src --out-dir lib --ignore src/__tests__/", | ||
"postbuild": "node ./scripts/postbuild.js", | ||
|
@@ -27,14 +29,7 @@ | |
"type": "git", | ||
"url": "git+ssh://[email protected]/reactstrap/reactstrap.git" | ||
}, | ||
"files": [ | ||
"LICENSE", | ||
"README.md", | ||
"CHANGELOG.md", | ||
"lib", | ||
"dist", | ||
"src" | ||
], | ||
"files": ["LICENSE", "README.md", "CHANGELOG.md", "lib", "dist", "src"], | ||
"keywords": [ | ||
"reactstrap", | ||
"bootstrap", | ||
|
@@ -86,7 +81,8 @@ | |
"edgji (https://github.com/edgji)", | ||
"nlrowe (https://github.com/nlrowe)", | ||
"npm-to-cdn-bot (by Forbes Lindesay) (https://github.com/npmcdn-to-unpkg-bot)", | ||
"polmauri (https://github.com/polmauri)" | ||
"polmauri (https://github.com/polmauri)", | ||
"Steven Scaffidi (https://github.com/sscaff1)" | ||
], | ||
"license": "MIT", | ||
"bugs": { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import React, { Component } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import Collapse from './Collapse'; | ||
import { findDOMElements, defaultToggleEvents, addMultipleEventListeners } from './utils'; | ||
|
||
const propTypes = { | ||
toggler: PropTypes.string.isRequired, | ||
toggleEvents: PropTypes.arrayOf(PropTypes.string) | ||
}; | ||
|
||
const defaultProps = { | ||
toggleEvents: defaultToggleEvents | ||
}; | ||
|
||
class UncontrolledCollapse extends Component { | ||
constructor(props) { | ||
super(props); | ||
|
||
this.togglers = null; | ||
this.removeEventListeners = null; | ||
this.toggle = this.toggle.bind(this); | ||
|
||
this.state = { | ||
isOpen: false | ||
}; | ||
} | ||
|
||
componentDidMount() { | ||
this.togglers = findDOMElements(this.props.toggler); | ||
if (this.togglers.length) { | ||
this.removeEventListeners = addMultipleEventListeners( | ||
this.togglers, | ||
this.toggle, | ||
this.props.toggleEvents | ||
); | ||
} | ||
} | ||
|
||
componentWillUnmount() { | ||
if (this.togglers.length && this.removeEventListeners) { | ||
this.removeEventListeners(); | ||
} | ||
} | ||
|
||
toggle() { | ||
this.setState(({ isOpen }) => ({ isOpen: !isOpen })); | ||
} | ||
|
||
render() { | ||
const { toggleEvents, ...rest } = this.props; | ||
return <Collapse isOpen={this.state.isOpen} {...rest} />; | ||
} | ||
} | ||
|
||
UncontrolledCollapse.propTypes = propTypes; | ||
UncontrolledCollapse.defaultProps = defaultProps; | ||
|
||
export default UncontrolledCollapse; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import React from 'react'; | ||
import { mount, shallow } from 'enzyme'; | ||
import { Collapse, UncontrolledCollapse } from '../'; | ||
|
||
describe('UncontrolledCollapse', () => { | ||
let toggler; | ||
let togglers; | ||
|
||
beforeEach(() => { | ||
document.body.innerHTML = ` | ||
<div> | ||
<button id="toggler">Click Me</button> | ||
<button class="toggler">Toggler 1</button> | ||
<button class="toggler">Toggler 2</button> | ||
</div>`; | ||
toggler = document.getElementById('toggler'); | ||
togglers = document.getElementsByClassName('toggler'); | ||
}); | ||
|
||
afterEach(() => { | ||
if (jest.isMockFunction(UncontrolledCollapse.prototype.toggle)) { | ||
UncontrolledCollapse.prototype.toggle.mockRestore(); | ||
} | ||
document.body.innerHTML = ''; | ||
toggler = null; | ||
togglers = null; | ||
}); | ||
|
||
it('should be a Collapse', () => { | ||
const collapse = shallow(<UncontrolledCollapse toggler="#toggler">Yo!</UncontrolledCollapse>); | ||
|
||
expect(collapse.type()).toBe(Collapse); | ||
}); | ||
|
||
it('should have isOpen default to false', () => { | ||
const collapse = shallow(<UncontrolledCollapse toggler="#toggler">Yo!</UncontrolledCollapse>); | ||
|
||
expect(collapse.prop('isOpen')).toBe(false); | ||
}); | ||
|
||
it('should toggle isOpen when toggle is called', () => { | ||
const collapse = shallow(<UncontrolledCollapse toggler="#toggler">Yo!</UncontrolledCollapse>); | ||
|
||
toggler.click(); | ||
collapse.update(); | ||
|
||
expect(collapse.prop('isOpen')).toBe(true); | ||
}); | ||
|
||
it('should call toggle when toggler is clicked', () => { | ||
jest.spyOn(UncontrolledCollapse.prototype, 'toggle'); | ||
mount(<UncontrolledCollapse toggler="#toggler">Yo!</UncontrolledCollapse>); | ||
|
||
expect(UncontrolledCollapse.prototype.toggle.mock.calls.length).toBe(0); | ||
|
||
toggler.click(); | ||
|
||
expect(UncontrolledCollapse.prototype.toggle.mock.calls.length).toBe(1); | ||
}); | ||
|
||
it('should toggle for multiple togglers', () => { | ||
const collapse = shallow(<UncontrolledCollapse toggler=".toggler">Yo!</UncontrolledCollapse>); | ||
|
||
expect(collapse.prop('isOpen')).toBe(false); | ||
|
||
togglers[0].click(); | ||
collapse.update(); | ||
|
||
expect(collapse.prop('isOpen')).toBe(true); | ||
|
||
togglers[1].click(); | ||
collapse.update(); | ||
|
||
expect(collapse.prop('isOpen')).toBe(false); | ||
}); | ||
|
||
it('should remove eventListeners when unmounted', () => { | ||
jest.spyOn(UncontrolledCollapse.prototype, 'componentWillUnmount'); | ||
jest.spyOn(UncontrolledCollapse.prototype, 'toggle'); | ||
|
||
const wrapper = mount(<UncontrolledCollapse toggler="#toggler">Yo!</UncontrolledCollapse>); | ||
|
||
expect(UncontrolledCollapse.prototype.toggle.mock.calls.length).toBe(0); | ||
expect(UncontrolledCollapse.prototype.componentWillUnmount.mock.calls.length).toBe(0); | ||
|
||
toggler.click(); | ||
|
||
expect(UncontrolledCollapse.prototype.toggle.mock.calls.length).toBe(1); | ||
|
||
wrapper.unmount(); | ||
|
||
expect(UncontrolledCollapse.prototype.componentWillUnmount.mock.calls.length).toBe(1); | ||
|
||
toggler.click(); | ||
|
||
expect(UncontrolledCollapse.prototype.toggle.mock.calls.length).toBe(1); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.