diff --git a/README.md b/README.md
index ee438b9d1..b98a9afdd 100644
--- a/README.md
+++ b/README.md
@@ -97,6 +97,7 @@ import ReactDOM from 'react-dom';
* [CountDown](#countdown)
* [FileDrop](#filedrop)
* [Mailto](#mailto)
+* [Modal](#modal)
* [StarRating](#starrating)
* [Tabs](#tabs)
* [Ticker](#ticker)
@@ -1206,12 +1207,152 @@ ReactDOM.render(
[⬆ Back to top](#table-of-contents)
+### Modal
+
+Renders a Modal component, controllable through events.
+To use the component, import `Modal` only once and then display it by passing a boolean value to the `isVisible` attribute.
+
+* Use object destructuring to set defaults for certain attributes of the modal component.
+* Define `keydownHandler`, a method which handles all keyboard events, which can be used according to your needs to dispatch actions (e.g. close the modal when Esc is pressed).
+* Use `React.useEffect()` hook to add or remove the `keydown` event listener, which calls `keydownHandler`.
+* Use the `isVisible` prop to determine if the modal should be shown or not.
+* Use CSS to style and position the modal component.
+
+```css
+.modal {
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right:0;
+ width: 100%;
+ z-index: 9999;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: rgba(0, 0, 0, 0.25);
+ animation-name: appear;
+ animation-duration: 300ms;
+}
+
+.modal-dialog{
+ width: 100%;
+ max-width: 550px;
+ background: white;
+ position: relative;
+ margin: 0 20px;
+ max-height: calc(100vh - 40px);
+ text-align: left;
+ display: flex;
+ flex-direction: column;
+ overflow:hidden;
+ box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
+ -webkit-animation-name: animatetop;
+ -webkit-animation-duration: 0.4s;
+ animation-name: slide-in;
+ animation-duration: 0.5s;
+}
+
+.modal-header,.modal-footer{
+ display: flex;
+ align-items: center;
+ padding: 1rem;
+}
+.modal-header{
+ border-bottom: 1px solid #dbdbdb;
+ justify-content: space-between;
+}
+.modal-footer{
+ border-top: 1px solid #dbdbdb;
+ justify-content: flex-end;
+}
+.modal-close{
+ cursor: pointer;
+ padding: 1rem;
+ margin: -1rem -1rem -1rem auto;
+}
+.modal-body{
+ overflow: auto;
+}
+.modal-content{
+ padding: 1rem;
+}
+
+@keyframes appear {
+ from {opacity: 0;}
+ to {opacity: 1;}
+}
+@keyframes slide-in {
+ from {transform: translateY(-150px);}
+ to { transform: translateY(0);}
+}
+```
+
+```jsx
+function Modal({ isVisible = false, title, content, footer, onClose }){
+ React.useEffect(() => {
+ document.addEventListener('keydown', keydownHandler);
+ return () => document.removeEventListener('keydown', keydownHandler);
+ });
+
+ function keydownHandler({ key }) {
+ switch (key) {
+ case 'Escape': onClose(); break;
+ default:
+ }
+ }
+
+ return !isVisible ? null : (
+
+
e.stopPropagation()}>
+
+
{title}
+ ×
+
+
+
{ content }
+
+ {footer &&
{footer}
}
+
+
+ )
+}
+```
+
+
+Examples
+
+```jsx
+//Add the component to the render function
+function App() {
+ const [ isModal, setModal] = React.useState(false);
+
+ return (
+
+
+ Add your content here}
+ footer = {}
+ onClose ={()=> setModal(false)}
+ />
+
+ )
+}
+
+ReactDOM.render( , document.getElementById('root'));
+```
+
+
+ [⬆ Back to top](#table-of-contents)
+
### StarRating
Renders a star rating component.
* Define a component, called `Star` that will render each individual star with the appropriate appearance, based on the parent component's state.
-* In the `StarRating` component, use the `React.setState()` hook to define the `rating` and `selection` state variables with the initial values of `props.rating` (or `0` if invalid or not supplied) and `0`.
+* In the `StarRating` component, use the `React.useState()` hook to define the `rating` and `selection` state variables with the initial values of `props.rating` (or `0` if invalid or not supplied) and `0`.
* Create a method, `hoverOver`, that updates `selected` and `rating` according to the provided `event`.
* Create a `
` to wrap the `` components, which are created using `Array.prototype.map` on an array of 5 elements, created using `Array.from`, and handle the `onMouseLeave` event to set `selection` to `0`, the `onClick` event to set the `rating` and the `onMouseOver` event to set `selection` to the `star-id` attribute of the `event.target` respectively.
* Finally, pass the appropriate values to each `` component (`starId` and `marked`).
@@ -1237,7 +1378,7 @@ function StarRating(props) {
return (
hoverOver(null)}
- onClick={() => setRating(event.target.getAttribute('star-id') || this.state.rating)}
+ onClick={(event) => setRating(event.target.getAttribute('star-id') || this.state.rating)}
onMouseOver={hoverOver}
>
{Array.from({ length: 5 }, (v, i) => (
diff --git a/data/snippet_data.json b/data/snippet_data.json
index a6fec14f8..cd37c9bf9 100644
--- a/data/snippet_data.json
+++ b/data/snippet_data.json
@@ -204,6 +204,22 @@
""
]
},
+ {
+ "name": "Modal.md",
+ "title": "Modal",
+ "text": "Renders a Modal component, controllable through events.\nTo use the component, import `Modal` only once and then display it by passing a boolean value to the `isVisible` attribute.\n\n* Use object destructuring to set defaults for certain attributes of the modal component.\n* Define `keydownHandler`, a method which handles all keyboard events, which can be used according to your needs to dispatch actions (e.g. close the modal when Esc is pressed).\n* Use `React.useEffect()` hook to add or remove the `keydown` event listener, which calls `keydownHandler`.\n* Use the `isVisible` prop to determine if the modal should be shown or not.\n* Use CSS to style and position the modal component.\n\n",
+ "codeBlocks": [
+ "```css\n.modal {\n position: fixed;\n top: 0;\n bottom: 0;\n left: 0;\n right:0;\n width: 100%;\n z-index: 9999; \n display: flex;\n align-items: center;\n justify-content: center;\n background-color: rgba(0, 0, 0, 0.25);\n animation-name: appear;\n animation-duration: 300ms;\n}\n\n.modal-dialog{\n width: 100%;\n max-width: 550px;\n background: white;\n position: relative;\n margin: 0 20px;\n max-height: calc(100vh - 40px);\n text-align: left;\n display: flex;\n flex-direction: column;\n overflow:hidden;\n box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);\n -webkit-animation-name: animatetop;\n -webkit-animation-duration: 0.4s;\n animation-name: slide-in;\n animation-duration: 0.5s;\n}\n\n.modal-header,.modal-footer{\n display: flex;\n align-items: center;\n padding: 1rem;\n}\n.modal-header{\n border-bottom: 1px solid #dbdbdb;\n justify-content: space-between;\n}\n.modal-footer{\n border-top: 1px solid #dbdbdb;\n justify-content: flex-end;\n}\n.modal-close{\n cursor: pointer;\n padding: 1rem;\n margin: -1rem -1rem -1rem auto;\n}\n.modal-body{\n overflow: auto;\n}\n.modal-content{\n padding: 1rem;\n}\n\n@keyframes appear {\n from {opacity: 0;}\n to {opacity: 1;}\n}\n@keyframes slide-in {\n from {transform: translateY(-150px);}\n to { transform: translateY(0);}\n}\n```",
+ "```jsx\nfunction Modal({ isVisible = false, title, content, footer, onClose }){ \n React.useEffect(() => {\n document.addEventListener('keydown', keydownHandler);\n return () => document.removeEventListener('keydown', keydownHandler);\n });\n\n function keydownHandler({ key }) {\n switch (key) {\n case 'Escape': onClose(); break;\n default:\n }\n }\n\n return !isVisible ? null : (\n
\n
e.stopPropagation()}>\n
\n
{title}
\n ×\n
\n
\n
{ content }
\n
\n {footer &&
{footer}
}\n
\n
\n )\n}\n```",
+ "```jsx\n//Add the component to the render function\nfunction App() {\n const [ isModal, setModal] = React.useState(false);\n \n return (\n \n \n Add your content here}\n footer = {}\n onClose ={()=> setModal(false)}\n />\n \n )\n}\n\nReactDOM.render( , document.getElementById('root'));\n```"
+ ],
+ "expertise": 2,
+ "tags": [
+ "visual",
+ "effect"
+ ],
+ "notes": []
+ },
{
"name": "MultiselectCheckbox.md",
"title": "MultiselectCheckbox",
@@ -266,9 +282,9 @@
{
"name": "StarRating.md",
"title": "StarRating",
- "text": "Renders a star rating component.\n\n* Define a component, called `Star` that will render each individual star with the appropriate appearance, based on the parent component's state.\n* In the `StarRating` component, use the `React.setState()` hook to define the `rating` and `selection` state variables with the initial values of `props.rating` (or `0` if invalid or not supplied) and `0`.\n* Create a method, `hoverOver`, that updates `selected` and `rating` according to the provided `event`.\n* Create a `
` to wrap the `` components, which are created using `Array.prototype.map` on an array of 5 elements, created using `Array.from`, and handle the `onMouseLeave` event to set `selection` to `0`, the `onClick` event to set the `rating` and the `onMouseOver` event to set `selection` to the `star-id` attribute of the `event.target` respectively.\n* Finally, pass the appropriate values to each `` component (`starId` and `marked`).\n\n",
+ "text": "Renders a star rating component.\n\n* Define a component, called `Star` that will render each individual star with the appropriate appearance, based on the parent component's state.\n* In the `StarRating` component, use the `React.useState()` hook to define the `rating` and `selection` state variables with the initial values of `props.rating` (or `0` if invalid or not supplied) and `0`.\n* Create a method, `hoverOver`, that updates `selected` and `rating` according to the provided `event`.\n* Create a `
` to wrap the `` components, which are created using `Array.prototype.map` on an array of 5 elements, created using `Array.from`, and handle the `onMouseLeave` event to set `selection` to `0`, the `onClick` event to set the `rating` and the `onMouseOver` event to set `selection` to the `star-id` attribute of the `event.target` respectively.\n* Finally, pass the appropriate values to each `` component (`starId` and `marked`).\n\n",
"codeBlocks": [
- "```jsx\nfunction Star({ marked, starId }) {\n return (\n \n {marked ? '\\u2605' : '\\u2606'}\n \n );\n}\n\nfunction StarRating(props) {\n const [rating, setRating] = React.useState(typeof props.rating == 'number' ? props.rating : 0);\n const [selection, setSelection] = React.useState(0);\n const hoverOver = event => {\n let val = 0;\n if (event && event.target && event.target.getAttribute('star-id'))\n val = event.target.getAttribute('star-id');\n setSelection(val);\n };\n return (\n