Merge pull request #17 from zhongdeming428/feature/modal_dialog
add modal/dialog
This commit is contained in:
141
snippets/ModalDialog.md
Normal file
141
snippets/ModalDialog.md
Normal file
@ -0,0 +1,141 @@
|
||||
### ModalDialog
|
||||
|
||||
Renders a dialog component in a modal, controllable through events.
|
||||
To use the component, import `ModalDialog` only once and then display it using `ModalDialog.show()`, passing the JSX templates and data as parameters.
|
||||
|
||||
Define `modalHandler`, a method that will handle showing the modal dialog, set `state` to the default values initially and bind the `close` and `modalClick` methods to the component's context.
|
||||
Define `close` and `modalClick` to toggle the visibility of the modal dialog, based on `state.closeOnClick`.
|
||||
Use the CustomEvent API to listen for `modal` events, that can be dispatched from the `static` `show()` method, handle listeners appropriately from `componentDidMount` and `componentWillUnmount`.
|
||||
|
||||
The `show()` method accepts an argument, that should contain three parameters:
|
||||
* `title`, a string for the dialog's title
|
||||
* `closeOnClick`, `true` if the modal should close on click or `false` if it should only close when clicking the *X* button
|
||||
* `content`, which is the JSX content to be rendered inside the dialog
|
||||
|
||||
Finally, in the `render()` method, use a `<div>` to wrap everything and render the modal dialog with the content passed to `show()`.
|
||||
|
||||
```css
|
||||
.modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
z-index: 9998;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.dialog {
|
||||
background-color: white;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.dialog-title {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
padding: 0 16px;
|
||||
border-bottom: 0.5px solid #c3c3c3;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.dialog-close {
|
||||
font-size: 32px;
|
||||
color: #c3c3c3;
|
||||
cursor: pointer;
|
||||
transform: rotate(45deg);
|
||||
user-select: none;
|
||||
}
|
||||
.dialog-close:hover {
|
||||
color: red;
|
||||
}
|
||||
.dialog-content {
|
||||
min-width: 300px;
|
||||
}
|
||||
```
|
||||
|
||||
```jsx
|
||||
class ModalDialog extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.modalHandler = (e) => {
|
||||
this.setState({
|
||||
data: e.detail.data,
|
||||
visible: true
|
||||
});
|
||||
};
|
||||
this.state = {
|
||||
data: {
|
||||
title: '',
|
||||
closeOnClick: false,
|
||||
content: ''
|
||||
},
|
||||
visible: false
|
||||
};
|
||||
this.close = this.close.bind(this);
|
||||
this.modalClick = this.modalClick.bind(this);
|
||||
}
|
||||
render() {
|
||||
return !this.state.visible ? null : <div className="modal" onClick={this.modalClick}>
|
||||
<div className="dialog">
|
||||
<div className="dialog-title">{ this.state.data.title }<span className="dialog-close" onClick={this.close}>+</span></div>
|
||||
<div className="dialog-content">
|
||||
{
|
||||
this.state.data.content
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
componentDidMount() {
|
||||
document.addEventListener('modal', this.modalHandler);
|
||||
}
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('modal', this.modalHandler);
|
||||
}
|
||||
close() {
|
||||
this.setState({
|
||||
visible: false,
|
||||
data: {
|
||||
title: '',
|
||||
closeOnClick: false,
|
||||
content: ''
|
||||
}
|
||||
});
|
||||
}
|
||||
static show(data) {
|
||||
document.dispatchEvent(new CustomEvent('modal', {
|
||||
detail: {
|
||||
data
|
||||
}
|
||||
}));
|
||||
}
|
||||
modalClick() {
|
||||
if (this.state.data.closeOnClick) this.close();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```jsx
|
||||
// add to render function
|
||||
<ModalDialog />
|
||||
|
||||
// every time you wanna call the dialog
|
||||
// content is a jsx element
|
||||
ModalDialog.show({
|
||||
title: 'Hello, world!',
|
||||
closeOnClick: true,
|
||||
content: <img src="https://github.com/30-seconds/30-seconds-of-react/blob/master/logo.png"/>
|
||||
});
|
||||
```
|
||||
|
||||
#### Notes:
|
||||
* This component includes a lot of CSS, which might conflict with other CSS in your project.
|
||||
* A more up-to-date method with lower compatibility is to use [Portals](https://reactjs.org/docs/portals.html) in React 16+.
|
||||
|
||||
<!-- tags: visual,static,children,state,class -->
|
||||
|
||||
<!-- expertise: 1 -->
|
||||
Reference in New Issue
Block a user