{ "data": [ { "id": "Accordion", "title": "Accordion", "type": "snippet", "attributes": { "fileName": "Accordion.md", "text": "Renders an accordion menu with multiple collapsible content components.\n\n* Define an `AccordionItem` component, pass it to the `Accordion` and remove unnecessary nodes expect for `AccordionItem` by identifying the function's name in `props.children`.\n* Each `AccordionItem` component renders a `\r\n \r\n {props.children}\r\n \r\n \r\n );\r\n}\r\n\r\nfunction Accordion(props) {\r\n const [bindIndex, setBindIndex] = React.useState(props.defaultIndex);\r\n\r\n const changeItem = itemIndex => {\r\n if (typeof props.onItemClick === 'function') props.onItemClick(itemIndex);\r\n if (itemIndex !== bindIndex) setBindIndex(itemIndex);\r\n };\r\n const items = props.children.filter(item => item.type.name === 'AccordionItem');\r\n\r\n return (\r\n
\r\n {items.map(({ props }) => (\r\n changeItem(props.index)}\r\n children={props.children}\r\n />\r\n ))}\r\n
\r\n );\r\n}", "example": "ReactDOM.render(\r\n \r\n \r\n Lorem ipsum\r\n \r\n \r\n Dolor sit amet\r\n \r\n ,\r\n document.getElementById('root')\r\n);" }, "tags": [ "visual", "children", "state", "advanced" ] }, "meta": { "hash": "7787feea6f6ad8bb1b1a73cf2938673d41fbc0dc8b29d5ebbbafe572784d963e" } }, { "id": "AutoLink", "title": "AutoLink", "type": "snippet", "attributes": { "fileName": "AutoLink.md", "text": "Renders a string as plaintext, with URLs converted to appropriate `` elements.\n\n* Use `String.prototype.split()` and `String.prototype.match()` with a regular expression to find URLs in a string.\n* Return 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": { "style": "", "code": "function AutoLink({ text }) {\r\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;\r\n\r\n return (\r\n \r\n {text.split(delimiter).map(word => {\r\n let match = word.match(delimiter);\r\n if (match) {\r\n let url = match[0];\r\n return {url};\r\n }\r\n return word;\r\n })}\r\n \r\n );\r\n}", "example": "ReactDOM.render(\r\n ,\r\n document.getElementById('root')\r\n);" }, "tags": [ "string", "fragment", "regexp", "advanced" ] }, "meta": { "hash": "4ca8f86fe197110cbdc91241f1c93ccb31ebe23f9b8eabe00f23c31f1939db1f" } }, { "id": "Carousel", "title": "Carousel", "type": "snippet", "attributes": { "fileName": "Carousel.md", "text": "Renders a carousel component.\n\n* Use the `React.setState()` hook to create the `active` state variable and give it a value of `0` (index of the first item).\n* Use an object, `style`, to hold the styles for the individual components.\n* Use the `React.setEffect()` hook to update the value of `active` to the index of the next item, using `setTimeout`.\n* Destructure `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.\n* Render the carousel items using `React.cloneElement()` and pass down rest `props` along with the computed styles.\n\n", "codeBlocks": { "style": "", "code": "function Carousel(props) {\r\n const [active, setActive] = React.useState(0);\r\n let scrollInterval = null;\r\n const style = {\r\n carousel: {\r\n position: 'relative'\r\n },\r\n carouselItem: {\r\n position: 'absolute',\r\n visibility: 'hidden'\r\n },\r\n visible: {\r\n visibility: 'visible'\r\n }\r\n };\r\n React.useEffect(() => {\r\n scrollInterval = setTimeout(() => {\r\n const { carouselItems } = props;\r\n setActive((active + 1) % carouselItems.length);\r\n }, 2000);\r\n });\r\n const { carouselItems, ...rest } = props;\r\n return (\r\n
\r\n {carouselItems.map((item, index) => {\r\n const activeStyle = active === index ? style.visible : {};\r\n return React.cloneElement(item, {\r\n ...rest,\r\n style: {\r\n ...style.carouselItem,\r\n ...activeStyle\r\n }\r\n });\r\n })}\r\n
\r\n );\r\n}", "example": "ReactDOM.render(\r\n carousel item 1,\r\n
carousel item 2
,\r\n
carousel item 3
\r\n ]}\r\n />,\r\n document.getElementById('root')\r\n);" }, "tags": [ "visual", "children", "state", "effect", "intermediate" ] }, "meta": { "hash": "c585316c31ab75c906dd8a9023474bfd68eb37dde735039bcca6067a2acd2894" } }, { "id": "ClickOutAndInside", "title": "ClickInside and ClickOutside", "type": "snippet", "attributes": { "fileName": "ClickOutAndInside.md", "text": "Two handy hooks to handle the click outside and inside event on the wrapped component.\n\n* Create customized hooks that take in a `ref` component(node) and a `callback` function to hanlde the customized `click` event\n* Use the `React.useEffect()` hook to append and clean up the `click` event.\n* Use the `React.useRef()` hook to create a `ref` for your click component and pass it to `useClickInside` and `useClickOutside` hooks.\n\n", "codeBlocks": { "style": ".click-box {\r\n border: 2px dashed orangered;\r\n height: 200px;\r\n width: 400px;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n}\r\n\r\np {\r\n border: 2px solid blue;\r\n padding: 16px;\r\n}", "code": "const useClickInside = (ref, callback) => {\r\n const handleClick = e => {\r\n //use the node contains to verify if we click inside\r\n if (ref.current && ref.current.contains(e.target)) {\r\n callback();\r\n }\r\n };\r\n\r\n //clean up using useEffect\r\n useEffect(() => {\r\n document.addEventListener(\"click\", handleClick);\r\n return () => {\r\n document.removeEventListener(\"click\", handleClick);\r\n };\r\n });\r\n};\r\n\r\nconst useClickOutside = (ref, callback) => {\r\n const handleClick = e => {\r\n //use the node contains to verify if we click outside\r\n if (ref.current && !ref.current.contains(e.target)) {\r\n callback();\r\n }\r\n };\r\n // clean up using useEffect\r\n useEffect(() => {\r\n document.addEventListener(\"click\", handleClick);\r\n return () => {\r\n document.removeEventListener(\"click\", handleClick);\r\n };\r\n });\r\n};\r\n\r\nfunction ClickBox({onClickOutside,onClickInside}) {\r\n const clickRef = useRef();\r\n useClickOutside(clickRef, onClickOutside);\r\n useClickInside(clickRef, onClickInside);\r\n return (\r\n
\r\n

Hello Click Me Inside!

\r\n
\r\n );\r\n}", "example": "ReactDOM.render( alert(\"click outside\")} onClickInside={()=> alert(\"click inside\")}/>,document.getElementById('root'))" }, "tags": [ "hooks", "effect", "event", "intermediate" ] }, "meta": { "hash": "773cb2ce0e28ff705f350ff82398836268bce65b32a2b93664bd535fbeed61e8" } }, { "id": "Collapse", "title": "Collapse", "type": "snippet", "attributes": { "fileName": "Collapse.md", "text": "Renders a component with collapsible content.\n\n* Use the `React.setState()` hook to create the `isCollapsed` state variable with an initial value of `props.collapsed`.\n* Use an object, `style`, to hold the styles for individual components and their states.\n* Use a `
` to wrap both the `\r\n \r\n {props.children}\r\n
\r\n \r\n );\r\n}", "example": "ReactDOM.render(\r\n \r\n

This is a collapse

\r\n

Hello world!

\r\n
,\r\n document.getElementById('root')\r\n);" }, "tags": [ "visual", "children", "state", "intermediate" ] }, "meta": { "hash": "0fb184a53478714a3eb9d9906f7661d5fa416db6bdb2b2b819add2ffb38f2a22" } }, { "id": "CountDown", "title": "CountDown", "type": "snippet", "attributes": { "fileName": "CountDown.md", "text": "Renders a countdown timer that prints a message when it reaches zero.\n\n* Use object destructuring to set defaults for the `hours`, `minutes` and `seconds` props.\n* Use the `React.useState()` hook to create the `time`, `paused` and `over` state variables and set their values to the values of the passed props, `false` and `false` respectively.\n* Create a method `tick`, that updates the value of `time` based on the current value (i.e. decreasing the time by one second).\n* If `paused` or `over` is `true`, `tick` will return immediately.\n* Create a method `reset`, that resets all state variables to their initial states.\n* Use the the `React.useEffect()` hook to call the `tick` method every second via the use of `setInterval()` and use `clearInterval()` to cleanup when the component is unmounted.\n* Use a `
` to wrap a `

` element with the textual representation of the components `time` state variable, as well as two `\r\n \r\n

\r\n );\r\n}", "example": "ReactDOM.render(, document.getElementById('root'));" }, "tags": [ "visual", "state", "advanced" ] }, "meta": { "hash": "cab16a22ce97e7a90a4ca0717b62a185bcbcd37fa55dc6983c79ea5857f76aaf" } }, { "id": "DataList", "title": "DataList", "type": "snippet", "attributes": { "fileName": "DataList.md", "text": "Renders a list of elements from an array of primitives.\n\n* Use the value of the `isOrdered` prop to conditionally render a `
    ` or `
      ` list.\n* Use `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.\n* Omit the `isOrdered` prop to render a `
        ` list by default.\n\n", "codeBlocks": { "style": "", "code": "function DataList({ isOrdered, data }) {\r\n const list = data.map((val, i) =>
      • {val}
      • );\r\n return isOrdered ?
          {list}
        :
          {list}
        ;\r\n}", "example": "const names = ['John', 'Paul', 'Mary'];\r\nReactDOM.render(, document.getElementById('root'));\r\nReactDOM.render(, document.getElementById('root'));" }, "tags": [ "array", "beginner" ] }, "meta": { "hash": "0280f7d4991a3145a1263342ef5ffa2e845c24c0793a2a06d40ed29a450b1039" } }, { "id": "DataTable", "title": "DataTable", "type": "snippet", "attributes": { "fileName": "DataTable.md", "text": "Renders a table with rows dynamically created from an array of primitives.\n\n* Render a `` element with two columns (`ID` and `Value`).\n* Use `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": { "style": "", "code": "function DataTable({ data }) {\r\n return (\r\n
        \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {data.map((val, i) => (\r\n \r\n \r\n \r\n \r\n ))}\r\n \r\n
        IDValue
        {i}{val}
        \r\n );\r\n}", "example": "const people = ['John', 'Jesse'];\r\nReactDOM.render(, document.getElementById('root'));" }, "tags": [ "array", "beginner" ] }, "meta": { "hash": "6da7e808336fe96d699685abb7d93735693f6e8dfba4a84262b9e02a624da617" } }, { "id": "FileDrop", "title": "FileDrop", "type": "snippet", "attributes": { "fileName": "FileDrop.md", "text": "Renders a file drag and drop component for a single file.\n\n* Create a ref called `dropRef` for this component.\n* Use 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* Create the `handleDrag`, `handleDragIn`, `handleDragOut` and `handleDrop` methods to handle drag and drop functionality, bind them to the component's context.\n* Each 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`.\n* Return an appropriately styled `
        ` and use `drag` and `filename` to determine its contents and style.\n* Finally, bind the `ref` of the created `
        ` to `dropRef`.\n\n", "codeBlocks": { "style": ".filedrop {\r\n min-height: 120px;\r\n border: 3px solid #d3d3d3;\r\n text-align: center;\r\n font-size: 24px;\r\n padding: 32px;\r\n border-radius: 4px;\r\n}\r\n\r\n.filedrop.drag {\r\n border: 3px dashed #1e90ff;\r\n}\r\n\r\n.filedrop.ready {\r\n border: 3px solid #32cd32;\r\n}", "code": "function FileDrop(props) {\r\n const [drag, setDrag] = React.useState(false);\r\n const [filename, setFilename] = React.useState('');\r\n let dropRef = React.createRef();\r\n let dragCounter = 0;\r\n\r\n const handleDrag = e => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n };\r\n\r\n const handleDragIn = e => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n dragCounter++;\r\n if (e.dataTransfer.items && e.dataTransfer.items.length > 0) setDrag(true);\r\n };\r\n\r\n const handleDragOut = e => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n dragCounter--;\r\n if (dragCounter === 0) setDrag(false);\r\n };\r\n\r\n const handleDrop = e => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n setDrag(false);\r\n if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\r\n props.handleDrop(e.dataTransfer.files[0]);\r\n setFilename(e.dataTransfer.files[0].name);\r\n e.dataTransfer.clearData();\r\n dragCounter = 0;\r\n }\r\n };\r\n\r\n React.useEffect(() => {\r\n let div = dropRef.current;\r\n div.addEventListener('dragenter', handleDragIn);\r\n div.addEventListener('dragleave', handleDragOut);\r\n div.addEventListener('dragover', handleDrag);\r\n div.addEventListener('drop', handleDrop);\r\n return function cleanup() {\r\n div.removeEventListener('dragenter', handleDragIn);\r\n div.removeEventListener('dragleave', handleDragOut);\r\n div.removeEventListener('dragover', handleDrag);\r\n div.removeEventListener('drop', handleDrop);\r\n };\r\n });\r\n\r\n return (\r\n \r\n {filename && !drag ?
        {filename}
        :
        Drop files here!
        }\r\n
        \r\n );\r\n}", "example": "ReactDOM.render(, document.getElementById('root'));" }, "tags": [ "visual", "input", "state", "effect", "event", "intermediate" ] }, "meta": { "hash": "79742466c371960a0134df6158931d6468a2767fc0d21e20b6709bb46c737941" } }, { "id": "LimitedTextarea", "title": "LimitedTextarea", "type": "snippet", "attributes": { "fileName": "LimitedTextarea.md", "text": "Renders a textarea component with a character limit.\n\n* Use 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`.\n* Use the `React.useEffect()` hook to call the `setFormattedContent` method on the value of the `content` state variable.\n* Use a`
        ` to wrap both the`