diff --git a/snippet-template.md b/snippet-template.md index 8984fe93e..d57150e6f 100644 --- a/snippet-template.md +++ b/snippet-template.md @@ -23,6 +23,12 @@ class ComponentName extends React.Component { ReactDOM.render(, mountNode); ``` + +#### Notes: +* Things to remember when using this +* Other options that might be less appealing or have lower compatibility +* Common mistakes and issues + diff --git a/snippets/ModalDialog.md b/snippets/ModalDialog.md new file mode 100644 index 000000000..1dc392699 --- /dev/null +++ b/snippets/ModalDialog.md @@ -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 `
` 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 :
+
+
{ this.state.data.title }+
+
+ { + this.state.data.content + } +
+
+
+ } + 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 + + +// every time you wanna call the dialog +// content is a jsx element +ModalDialog.show({ + title: 'Hello, world!', + closeOnClick: true, + content: +}); +``` + +#### 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+. + + + +