feat: copy code button
This commit is contained in:
		| @@ -1,9 +1,11 @@ | ||||
| import Image from 'next/image' | ||||
| import CustomLink from './Link' | ||||
| import Pre from './Pre' | ||||
|  | ||||
| const MDXComponents = { | ||||
|   Image, | ||||
|   a: CustomLink, | ||||
|   pre: Pre, | ||||
| } | ||||
|  | ||||
| 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