` to wrap a `
` element with the textual representation of the components `time` state variable, as well as two `` elements that will pause/unpause and restart the timer respectively.\nIf `over` is `true`, the timer will display a message instead of the value of `time`.\n\n",
"codeBlocks": [
- "```jsx\nfunction CountDown({ hours = 0, minutes = 0, seconds = 0 }) {\n const [paused, setPaused] = React.useState(false);\n const [over, setOver] = React.useState(false);\n const [time, setTime] = React.useState({\n hours: parseInt(hours),\n minutes: parseInt(minutes),\n seconds: parseInt(seconds)\n });\n\n const tick = () => {\n if (paused || over) return;\n if (time.hours == 0 && time.minutes == 0 && time.seconds == 0)\n setOver(true);\n else if (time.minutes == 0 && time.seconds == 0)\n setTime({\n hours: time.hours - 1,\n minutes: 59,\n seconds: 59\n });\n else if (time.seconds == 0)\n setTime({\n hours: time.hours,\n minutes: time.minutes - 1,\n seconds: 59\n });\n else\n setTime({\n hours: time.hours,\n minutes: time.minutes,\n seconds: time.seconds - 1\n });\n };\n\n const reset = () => {\n setTime({\n hours: parseInt(hours),\n minutes: parseInt(minutes),\n seconds: parseInt(seconds)\n });\n setPaused(false);\n setOver(false);\n };\n\n React.useEffect(() => {\n let timerID = setInterval(() => tick(), 1000);\n return () => clearInterval(timerID);\n });\n\n return (\n \n
{`${time.hours\n .toString()\n .padStart(2, \"0\")}:${time.minutes\n .toString()\n .padStart(2, \"0\")}:${time.seconds.toString().padStart(2, \"0\")}`}
\n
{over ? \"Time's up!\" : \"\"}
\n
setPaused(!paused)}>\n {paused ? \"Resume\" : \"Pause\"}\n \n
reset()}>Restart \n
\n );\n}\n```",
- "```jsx\nReactDOM.render(\n ,\n document.getElementById('root')\n);\n```"
+ "```jsx\nfunction CountDown({ hours = 0, minutes = 0, seconds = 0 }) {\n const [paused, setPaused] = React.useState(false);\n const [over, setOver] = React.useState(false);\n const [time, setTime] = React.useState({\n hours: parseInt(hours),\n minutes: parseInt(minutes),\n seconds: parseInt(seconds)\n });\n\n const tick = () => {\n if (paused || over) return;\n if (time.hours == 0 && time.minutes == 0 && time.seconds == 0) setOver(true);\n else if (time.minutes == 0 && time.seconds == 0)\n setTime({\n hours: time.hours - 1,\n minutes: 59,\n seconds: 59\n });\n else if (time.seconds == 0)\n setTime({\n hours: time.hours,\n minutes: time.minutes - 1,\n seconds: 59\n });\n else\n setTime({\n hours: time.hours,\n minutes: time.minutes,\n seconds: time.seconds - 1\n });\n };\n\n const reset = () => {\n setTime({\n hours: parseInt(hours),\n minutes: parseInt(minutes),\n seconds: parseInt(seconds)\n });\n setPaused(false);\n setOver(false);\n };\n\n React.useEffect(() => {\n let timerID = setInterval(() => tick(), 1000);\n return () => clearInterval(timerID);\n });\n\n return (\n \n
{`${time.hours.toString().padStart(2, '0')}:${time.minutes\n .toString()\n .padStart(2, '0')}:${time.seconds.toString().padStart(2, '0')}`}
\n
{over ? \"Time's up!\" : ''}
\n
setPaused(!paused)}>{paused ? 'Resume' : 'Pause'} \n
reset()}>Restart \n
\n );\n}\n```",
+ "```jsx\nReactDOM.render( , document.getElementById('root'));\n```"
],
"expertise": 2,
- "tags": ["visual", "state"],
+ "tags": [
+ "visual",
+ "state"
+ ],
"notes": []
},
{
@@ -52,11 +68,13 @@
"title": "DataList",
"text": "Renders a list of elements from an array of primitives.\n\nUse the value of the `isOrdered` prop to conditionally render a `` or `` list.\nUse `Array.prototype.map` to render every item in `data` as a `` element, give it a `key` produced from the concatenation of the its index and value.\nOmit the `isOrdered` prop to render a `` list by default.\n\n",
"codeBlocks": [
- "```jsx\nfunction DataList({ isOrdered, data }) {\n const list = data.map((val, i) => (\n {val} \n ));\n return isOrdered ? {list} : ;\n}\n```",
- "```jsx\nconst names = ['John', 'Paul', 'Mary'];\nReactDOM.render(, document.getElementById('root'));\nReactDOM.render( , document.getElementById('root'));\n```"
+ "```jsx\nfunction DataList({ isOrdered, data }) {\n const list = data.map((val, i) => {val} );\n return isOrdered ? {list} : ;\n}\n```",
+ "```jsx\nconst names = ['John', 'Paul', 'Mary'];\nReactDOM.render( , document.getElementById('root'));\nReactDOM.render( , document.getElementById('root'));\n```"
],
"expertise": 0,
- "tags": ["array"],
+ "tags": [
+ "array"
+ ],
"notes": []
},
{
@@ -64,24 +82,31 @@
"title": "DataTable",
"text": "Renders a table with rows dynamically created from an array of primitives.\n\nRender a `` element with two columns (`ID` and `Value`).\nUse `Array.prototype.map` to render every item in `data` as a `` element, consisting of its index and value, give it a `key` produced from the concatenation of the two.\n\n",
"codeBlocks": [
- "```jsx\nfunction DataTable({ data }) {\n return (\n \n \n \n ID \n Value \n \n \n \n {data.map((val, i) =>\n \n {i} \n {val} \n \n )}\n \n
\n );\n}\n```",
- "```jsx\nconst people = ['John', 'Jesse'];\nReactDOM.render(\n ,\n document.getElementById('root')\n);\n```"
+ "```jsx\nfunction DataTable({ data }) {\n return (\n \n \n \n ID \n Value \n \n \n \n {data.map((val, i) => (\n \n {i} \n {val} \n \n ))}\n \n
\n );\n}\n```",
+ "```jsx\nconst people = ['John', 'Jesse'];\nReactDOM.render( , document.getElementById('root'));\n```"
],
"expertise": 0,
- "tags": ["array"],
+ "tags": [
+ "array"
+ ],
"notes": []
},
{
"name": "FileDrop.md",
"title": "FileDrop",
- "text": "Renders a file drag and drop component for a single file.\n\nCreate a ref called `dropRef` for this component.\nUse the `React.useState()` hook to create the `drag` and `filename` variables, initialized to `false` and `''` respectively.\nThe variables `dragCounter` and `drag` are used to determine if a file is being dragged, while `filename` is used to store the dropped file's name.\n\nCreate the `handleDrag`, `handleDragIn`, `handleDragOut` and `handleDrop` methods to handle drag and drop functionality, bind them to the component's context.\nEach of the methods will handle a specific event, the listeners for which are created and removed in the `React.useEffect()` hook and its attached `cleanup()` method.\n`handleDrag` prevents the browser from opening the dragged file, `handleDragIn` and `handleDragOut` handle the dragged file entering and exiting the component, while `handleDrop` handles the file being dropped and passes it to `props.handleDrop`.\nReturn an appropriately styled `` and use `drag` and `filename` to determine its contents and style. \nFinally, bind the `ref` of the created `
` to `dropRef`.\n\n\n",
+ "text": "Renders a file drag and drop component for a single file.\n\nCreate a ref called `dropRef` for this component.\nUse the `React.useState()` hook to create the `drag` and `filename` variables, initialized to `false` and `''` respectively.\nThe variables `dragCounter` and `drag` are used to determine if a file is being dragged, while `filename` is used to store the dropped file's name.\n\nCreate the `handleDrag`, `handleDragIn`, `handleDragOut` and `handleDrop` methods to handle drag and drop functionality, bind them to the component's context.\nEach of the methods will handle a specific event, the listeners for which are created and removed in the `React.useEffect()` hook and its attached `cleanup()` method.\n`handleDrag` prevents the browser from opening the dragged file, `handleDragIn` and `handleDragOut` handle the dragged file entering and exiting the component, while `handleDrop` handles the file being dropped and passes it to `props.handleDrop`.\nReturn an appropriately styled `
` and use `drag` and `filename` to determine its contents and style.\nFinally, bind the `ref` of the created `
` to `dropRef`.\n\n",
"codeBlocks": [
- "```css\n.filedrop {\n min-height: 120px;\n border: 3px solid #D3D3D3;\n text-align: center;\n font-size: 24px;\n padding: 32px;\n border-radius: 4px;\n}\n\n.filedrop.drag {\n border: 3px dashed #1E90FF;\n}\n\n.filedrop.ready {\n border: 3px solid #32CD32;\n}\n```",
- "```jsx\nfunction FileDrop(props) {\n const [drag, setDrag] = React.useState(false);\n const [filename, setFilename] = React.useState('');\n let dropRef = React.createRef();\n let dragCounter = 0;\n\n const handleDrag = e => {\n e.preventDefault();\n e.stopPropagation();\n };\n\n const handleDragIn = e => {\n e.preventDefault();\n e.stopPropagation();\n dragCounter++;\n if (e.dataTransfer.items && e.dataTransfer.items.length > 0) setDrag(true);\n };\n\n const handleDragOut = e => {\n e.preventDefault();\n e.stopPropagation();\n dragCounter--;\n if (dragCounter === 0) setDrag(false);\n };\n\n const handleDrop = e => {\n e.preventDefault();\n e.stopPropagation();\n setDrag(false);\n if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n props.handleDrop(e.dataTransfer.files[0]);\n setFilename(e.dataTransfer.files[0].name);\n e.dataTransfer.clearData();\n dragCounter = 0;\n }\n };\n\n React.useEffect(() => {\n let div = dropRef.current;\n div.addEventListener(\"dragenter\", handleDragIn);\n div.addEventListener(\"dragleave\", handleDragOut);\n div.addEventListener(\"dragover\", handleDrag);\n div.addEventListener(\"drop\", handleDrop);\n return function cleanup() {\n div.removeEventListener(\"dragenter\", handleDragIn);\n div.removeEventListener(\"dragleave\", handleDragOut);\n div.removeEventListener(\"dragover\", handleDrag);\n div.removeEventListener(\"drop\", handleDrop);\n };\n });\n\n return (\n
\n {filename && !drag ?
{filename}
:
Drop files here!
}\n
\n );\n}\n```",
- "```jsx\nReactDOM.render(
, document.getElementById('root'));\n```"
+ "```css\n.filedrop {\n min-height: 120px;\n border: 3px solid #d3d3d3;\n text-align: center;\n font-size: 24px;\n padding: 32px;\n border-radius: 4px;\n}\n\n.filedrop.drag {\n border: 3px dashed #1e90ff;\n}\n\n.filedrop.ready {\n border: 3px solid #32cd32;\n}\n```",
+ "```jsx\nfunction FileDrop(props) {\n const [drag, setDrag] = React.useState(false);\n const [filename, setFilename] = React.useState('');\n let dropRef = React.createRef();\n let dragCounter = 0;\n\n const handleDrag = e => {\n e.preventDefault();\n e.stopPropagation();\n };\n\n const handleDragIn = e => {\n e.preventDefault();\n e.stopPropagation();\n dragCounter++;\n if (e.dataTransfer.items && e.dataTransfer.items.length > 0) setDrag(true);\n };\n\n const handleDragOut = e => {\n e.preventDefault();\n e.stopPropagation();\n dragCounter--;\n if (dragCounter === 0) setDrag(false);\n };\n\n const handleDrop = e => {\n e.preventDefault();\n e.stopPropagation();\n setDrag(false);\n if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n props.handleDrop(e.dataTransfer.files[0]);\n setFilename(e.dataTransfer.files[0].name);\n e.dataTransfer.clearData();\n dragCounter = 0;\n }\n };\n\n React.useEffect(() => {\n let div = dropRef.current;\n div.addEventListener('dragenter', handleDragIn);\n div.addEventListener('dragleave', handleDragOut);\n div.addEventListener('dragover', handleDrag);\n div.addEventListener('drop', handleDrop);\n return function cleanup() {\n div.removeEventListener('dragenter', handleDragIn);\n div.removeEventListener('dragleave', handleDragOut);\n div.removeEventListener('dragover', handleDrag);\n div.removeEventListener('drop', handleDrop);\n };\n });\n\n return (\n \n {filename && !drag ?
{filename}
:
Drop files here!
}\n
\n );\n}\n```",
+ "```jsx\nReactDOM.render( , document.getElementById('root'));\n```"
],
"expertise": 2,
- "tags": ["visual", "input", "state", "effect"],
+ "tags": [
+ "visual",
+ "input",
+ "state",
+ "effect"
+ ],
"notes": []
},
{
@@ -89,11 +114,13 @@
"title": "Input",
"text": "Renders an ` ` element that uses a callback function to pass its value to the parent component.\n\nUse object destructuring to set defaults for certain attributes of the ` ` element.\nRender an ` ` element with the appropriate attributes and use the `callback` function in the `onChange` event to pass the value of the input to the parent.\n\n",
"codeBlocks": [
- "```jsx\nfunction Input ({ callback, type = 'text', disabled = false, readOnly = false, placeholder = '' }) {\n return (\n callback(value)}\n />\n );\n}\n```",
- "```jsx\nReactDOM.render(\n console.log(val)}/>,\n document.getElementById('root')\n);\n```"
+ "```jsx\nfunction Input({ callback, type = 'text', disabled = false, readOnly = false, placeholder = '' }) {\n return (\n callback(value)}\n />\n );\n}\n```",
+ "```jsx\nReactDOM.render(\n console.log(val)} />,\n document.getElementById('root')\n);\n```"
],
"expertise": 0,
- "tags": ["input"],
+ "tags": [
+ "input"
+ ],
"notes": []
},
{
@@ -102,10 +129,14 @@
"text": "Renders a textarea component with a character limit.\n\nUse the `React.useState()` hook to create the `content` state variable and set its value to `value`.\nCreate a method `setFormattedContent`, which trims the content of the input if it's longer than `limit`.\nUse the `React.useEffect()` hook to call the `setFormattedContent` method on the value of the `content` state variable.\nUse a`