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 hoverOver(null)}\n onClick={() => setRating(event.target.getAttribute('star-id') || this.state.rating)}\n onMouseOver={hoverOver}\n >\n {Array.from({ length: 5 }, (v, i) => (\n = i + 1 : rating >= i + 1}\n />\n ))}\n
\n );\n}\n```", + "```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 hoverOver(null)}\n onClick={(event) => setRating(event.target.getAttribute('star-id') || this.state.rating)}\n onMouseOver={hoverOver}\n >\n {Array.from({ length: 5 }, (v, i) => (\n = i + 1 : rating >= i + 1}\n />\n ))}\n
\n );\n}\n```", "```jsx\nReactDOM.render(, document.getElementById('root'));\nReactDOM.render(, document.getElementById('root'));\n```" ], "expertise": 2,