upstream #1
| @@ -1,9 +1,11 @@ | |||||||
| import Image from 'next/image' | import Image from 'next/image' | ||||||
| import CustomLink from './Link' | import CustomLink from './Link' | ||||||
|  | import Pre from './Pre' | ||||||
|  |  | ||||||
| const MDXComponents = { | const MDXComponents = { | ||||||
|   Image, |   Image, | ||||||
|   a: CustomLink, |   a: CustomLink, | ||||||
|  |   pre: Pre, | ||||||
| } | } | ||||||
|  |  | ||||||
| export default MDXComponents | export default MDXComponents | ||||||
|   | |||||||
							
								
								
									
										70
									
								
								components/Pre.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								components/Pre.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | |||||||
|  | import { useState, useRef } from 'react' | ||||||
|  |  | ||||||
|  | const Pre = (props) => { | ||||||
|  |   const textInput = useRef(null) | ||||||
|  |   const [hovered, setHovered] = useState(false) | ||||||
|  |   const [copied, setCopied] = useState(false) | ||||||
|  |  | ||||||
|  |   const onEnter = () => { | ||||||
|  |     setHovered(true) | ||||||
|  |   } | ||||||
|  |   const onExit = () => { | ||||||
|  |     setHovered(false) | ||||||
|  |     setCopied(false) | ||||||
|  |   } | ||||||
|  |   const onCopy = () => { | ||||||
|  |     setCopied(true) | ||||||
|  |     navigator.clipboard.writeText(textInput.current.textContent) | ||||||
|  |     setTimeout(() => { | ||||||
|  |       setCopied(false) | ||||||
|  |     }, 2000) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return ( | ||||||
|  |     <pre ref={textInput} onMouseEnter={onEnter} onMouseLeave={onExit} className="relative"> | ||||||
|  |       {hovered && ( | ||||||
|  |         <button | ||||||
|  |           aria-label="Copy code" | ||||||
|  |           type="button" | ||||||
|  |           className={`absolute right-3 w-8 h-8 p-1 rounded border-2 bg-gray-700 dark:bg-gray-800 ${ | ||||||
|  |             copied | ||||||
|  |               ? 'focus:outline-none focus:border-green-400 border-green-400' | ||||||
|  |               : 'border-gray-300' | ||||||
|  |           }`} | ||||||
|  |           onClick={onCopy} | ||||||
|  |         > | ||||||
|  |           <svg | ||||||
|  |             xmlns="http://www.w3.org/2000/svg" | ||||||
|  |             viewBox="0 0 24 24" | ||||||
|  |             stroke="currentColor" | ||||||
|  |             fill="none" | ||||||
|  |             className={copied ? 'text-green-400' : 'text-gray-300'} | ||||||
|  |           > | ||||||
|  |             {copied ? ( | ||||||
|  |               <> | ||||||
|  |                 <path | ||||||
|  |                   strokeLinecap="round" | ||||||
|  |                   strokeLinejoin="round" | ||||||
|  |                   strokeWidth={2} | ||||||
|  |                   d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4" | ||||||
|  |                 /> | ||||||
|  |               </> | ||||||
|  |             ) : ( | ||||||
|  |               <> | ||||||
|  |                 <path | ||||||
|  |                   strokeLinecap="round" | ||||||
|  |                   strokeLinejoin="round" | ||||||
|  |                   strokeWidth={2} | ||||||
|  |                   d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" | ||||||
|  |                 /> | ||||||
|  |               </> | ||||||
|  |             )} | ||||||
|  |           </svg> | ||||||
|  |         </button> | ||||||
|  |       )} | ||||||
|  |       {props.children} | ||||||
|  |     </pre> | ||||||
|  |   ) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export default Pre | ||||||
		Reference in New Issue
	
	Block a user