63
app/components/UncontrolledModal/UncontrolledModal.js
Executable file
63
app/components/UncontrolledModal/UncontrolledModal.js
Executable file
@@ -0,0 +1,63 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import _ from 'lodash';
|
||||
import { Modal } from 'reactstrap';
|
||||
|
||||
import { Provider } from './context';
|
||||
|
||||
class UncontrolledModal extends React.Component {
|
||||
static propTypes = {
|
||||
target: PropTypes.string.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
isOpen: false
|
||||
};
|
||||
|
||||
this.boundClickEventHandler = this.clickEventHandler.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (typeof document !== 'undefined') {
|
||||
this.triggerElement = document.querySelector(`#${this.props.target}`);
|
||||
|
||||
if (!this.triggerElement) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('UncontrolledModal: \'target\' element has not been found in the DOM via querySelector');
|
||||
return;
|
||||
}
|
||||
|
||||
this.triggerElement.addEventListener('click', this.boundClickEventHandler);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.triggerElement) {
|
||||
this.triggerElement.removeEventListener('click', this.boundClickEventHandler);
|
||||
}
|
||||
}
|
||||
|
||||
clickEventHandler() {
|
||||
this.setState({ isOpen: true });
|
||||
}
|
||||
|
||||
render() {
|
||||
const modalProps = _.omit(this.props, ['target']);
|
||||
const toggleModal = () => { this.setState({ isOpen: !this.state.isOpen }) };
|
||||
|
||||
return (
|
||||
<Provider value={{ toggleModal }}>
|
||||
<Modal
|
||||
{ ...modalProps }
|
||||
isOpen={ this.state.isOpen }
|
||||
toggle={ toggleModal }
|
||||
/>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { UncontrolledModal };
|
34
app/components/UncontrolledModal/UncontrolledModalClose.js
Executable file
34
app/components/UncontrolledModal/UncontrolledModalClose.js
Executable file
@@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Button } from 'reactstrap';
|
||||
|
||||
import { Consumer } from './context';
|
||||
|
||||
const UncontrolledModalClose = (props) => {
|
||||
const { tag, ...otherProps } = props;
|
||||
const Tag = tag;
|
||||
|
||||
return (
|
||||
<Consumer>
|
||||
{
|
||||
(value) => (
|
||||
<Tag
|
||||
{ ...otherProps }
|
||||
onClick={ () => value.toggleModal() }
|
||||
/>
|
||||
)
|
||||
}
|
||||
</Consumer>
|
||||
)
|
||||
};
|
||||
UncontrolledModalClose.propTypes = {
|
||||
tag: PropTypes.oneOfType([
|
||||
PropTypes.func,
|
||||
PropTypes.string
|
||||
])
|
||||
};
|
||||
UncontrolledModalClose.defaultProps = {
|
||||
tag: Button
|
||||
};
|
||||
|
||||
export { UncontrolledModalClose };
|
8
app/components/UncontrolledModal/context.js
Executable file
8
app/components/UncontrolledModal/context.js
Executable file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
|
||||
const { Provider, Consumer } = React.createContext();
|
||||
|
||||
export {
|
||||
Provider,
|
||||
Consumer
|
||||
}
|
6
app/components/UncontrolledModal/index.js
Executable file
6
app/components/UncontrolledModal/index.js
Executable file
@@ -0,0 +1,6 @@
|
||||
import { UncontrolledModal } from './UncontrolledModal';
|
||||
import { UncontrolledModalClose } from './UncontrolledModalClose';
|
||||
|
||||
UncontrolledModal.Close = UncontrolledModalClose;
|
||||
|
||||
export default UncontrolledModal;
|
Reference in New Issue
Block a user