[ { "name": "AutoLink.md", "title": "AutoLink", "text": "Renders a string as plaintext, with URLs converted to appropriate `` elements.\n\nUse `String.prototype.split()` and `String.prototype.match()` with a regular expression to find URLs in a string.\nReturn a `` with matched URLs rendered as `` elements, dealing with missing protocol prefixes if necessary, and the rest of the string rendered as plaintext.\n\n", "codeBlocks": [ "```jsx\nfunction AutoLink({ text }) {\n const delimiter = /((?:https?:\\/\\/)?(?:(?:[a-z0-9]?(?:[a-z0-9\\-]{1,61}[a-z0-9])?\\.[^\\.|\\s])+[a-z\\.]*[a-z]+|(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3})(?::\\d{1,5})*[a-z0-9.,_\\/~#&=;%+?\\-\\\\(\\\\)]*)/gi;\n\n return (\n \n {text.split(delimiter).map(word => {\n let match = word.match(delimiter);\n if (match) {\n let url = match[0];\n return (\n {url}\n );\n }\n return word;\n })}\n \n );\n}\n```", "```jsx\nReactDOM.render(\n ,\n document.getElementById('root')\n);\n```" ], "expertise": 2, "tags": [ "string", "fragment", "regexp" ], "notes": [] }, { "name": "Carousel.md", "title": "Carousel", "text": "Renders a carousel component.\n\nUse the `React.setState()` hook to create the `active` state variable and give it a value of `0` (index of the first item).\nUse an object, `style`, to hold the styles for the individual components.\nUse the `React.setEffect()` hook to update the value of `active` to the index of the next item, using `setTimeout`.\nDestructure `props`, compute if visibility style should be set to `visible` or not for each carousel item while mapping over and applying the combined style to the carousel item component accordingly.\nRender the carousel items using `React.cloneElement()` and pass down rest `props` along with the computed styles.\n\n", "codeBlocks": [ "```jsx\nfunction Carousel(props) {\n const [active, setActive] = React.useState(0);\n let scrollInterval = null;\n const style = {\n carousel: {\n position: \"relative\"\n },\n carouselItem: {\n position: \"absolute\",\n visibility: \"hidden\"\n },\n visible: {\n visibility: \"visible\"\n }\n };\n React.useEffect(() => {\n scrollInterval = setTimeout(() => {\n const { carouselItems } = props;\n setActive((active + 1) % carouselItems.length);\n }, 2000);\n });\n const { carouselItems, ...rest } = props;\n return (\n
\n {carouselItems.map((item, index) => {\n const activeStyle = active === index ? style.visible : {};\n return React.cloneElement(item, {\n ...rest,\n style: {\n ...style.carouselItem,\n ...activeStyle\n }\n });\n })}\n
\n );\n}\n```", "```jsx\nReactDOM.render(\n carousel item 1,\n
carousel item 2
,\n
carousel item 3
\n ]}\n />,\n document.getElementById(\"root\")\n);\n ```" ], "expertise": 2, "tags": [ "visual", "children", "state", "effect" ], "notes": [] }, { "name": "Collapse.md", "title": "Collapse", "text": "Renders a component with collapsible content.\n\nUse the `React.setState()` hook to create the `isCollapsed` state variable with an initial value of `props.collapsed`.\nUse an object, `style`, to hold the styles for individual components and their states.\nUse a `
` to wrap both the `\n \n {props.children}\n
\n \n );\n}\n```", "```jsx\nReactDOM.render(\n \n

This is a collapse

\n

Hello world!

\n
,\n document.getElementById('root')\n);\n```" ], "expertise": 2, "tags": [ "visual", "children", "state" ], "notes": [] }, { "name": "DataList.md", "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}
        :
          {list}
        ;\n}\n```", "```jsx\nconst names = ['John', 'Paul', 'Mary'];\nReactDOM.render(, document.getElementById('root'));\nReactDOM.render(, document.getElementById('root'));\n```" ], "expertise": 0, "tags": [ "array" ], "notes": [] }, { "name": "DataTable.md", "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 \n \n \n \n \n {data.map((val, i) =>\n \n \n \n \n )}\n \n
        IDValue
        {i}{val}
        \n );\n}\n```", "```jsx\nconst people = ['John', 'Jesse'];\nReactDOM.render(\n ,\n document.getElementById('root')\n);\n```" ], "expertise": 0, "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", "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```" ], "expertise": 2, "tags": [ "visual", "input", "state", "effect" ], "notes": [] }, { "name": "Input.md", "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```" ], "expertise": 0, "tags": [ "input" ], "notes": [] }, { "name": "LimitedTextarea.md", "title": "LimitedTextarea", "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`
        ` to wrap both the`