feat: codeblock styling like chatgpt (#132)
This commit is contained in:
		
							parent
							
								
									c3132ef2fb
								
							
						
					
					
						commit
						e30336c00e
					
				|  | @ -1,5 +1,5 @@ | ||||||
| import { generateRandomString, programmingLanguages } from "@/utils/app/codeblock"; | import { generateRandomString, programmingLanguages } from "@/utils/app/codeblock"; | ||||||
| import { IconDownload } from "@tabler/icons-react"; | import { IconCheck, IconClipboard, IconDownload } from "@tabler/icons-react"; | ||||||
| import { FC, useState } from "react"; | import { FC, useState } from "react"; | ||||||
| import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; | import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; | ||||||
| import { oneDark, oneLight } from "react-syntax-highlighter/dist/cjs/styles/prism"; | import { oneDark, oneLight } from "react-syntax-highlighter/dist/cjs/styles/prism"; | ||||||
|  | @ -11,7 +11,7 @@ interface Props { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export const CodeBlock: FC<Props> = ({ language, value, lightMode }) => { | export const CodeBlock: FC<Props> = ({ language, value, lightMode }) => { | ||||||
|   const [buttonText, setButtonText] = useState("Copy code"); |   const [isCopied, setIsCopied] = useState<Boolean>(false); | ||||||
| 
 | 
 | ||||||
|   const copyToClipboard = () => { |   const copyToClipboard = () => { | ||||||
|     if (!navigator.clipboard || !navigator.clipboard.writeText) { |     if (!navigator.clipboard || !navigator.clipboard.writeText) { | ||||||
|  | @ -19,10 +19,10 @@ export const CodeBlock: FC<Props> = ({ language, value, lightMode }) => { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     navigator.clipboard.writeText(value).then(() => { |     navigator.clipboard.writeText(value).then(() => { | ||||||
|       setButtonText("Copied!"); |       setIsCopied(true); | ||||||
| 
 | 
 | ||||||
|       setTimeout(() => { |       setTimeout(() => { | ||||||
|         setButtonText("Copy code"); |         setIsCopied(false); | ||||||
|       }, 2000); |       }, 2000); | ||||||
|     }); |     }); | ||||||
|   }; |   }; | ||||||
|  | @ -48,21 +48,22 @@ export const CodeBlock: FC<Props> = ({ language, value, lightMode }) => { | ||||||
|     URL.revokeObjectURL(url); |     URL.revokeObjectURL(url); | ||||||
|   }; |   }; | ||||||
|   return ( |   return ( | ||||||
|     <div className="relative text-[16px]"> |     <div className="codeblock relative text-[16px] font-sans"> | ||||||
|       <div className="flex items-center justify-between"> |       <div className="flex items-center justify-between py-1.5 px-4"> | ||||||
|         <span className="text-xs text-white">{language}</span> |         <span className="text-xs text-white lowercase">{language}</span> | ||||||
|         <div className="flex items-center"> |         <div className="flex items-center"> | ||||||
|           <button |           <button | ||||||
|             className="text-white bg-none py-0.5 px-2 rounded focus:outline-none hover:bg-blue-700 text-xs" |             className="text-white bg-none py-0.5 px-2 rounded focus:outline-none text-xs flex items-center" | ||||||
|             onClick={copyToClipboard} |             onClick={copyToClipboard} | ||||||
|           > |           > | ||||||
|             {buttonText} |             {isCopied ? <IconCheck size={18} className="mr-1.5"/> : <IconClipboard size={18} className="mr-1.5"/>} | ||||||
|  |             {isCopied ? "Copied!" : "Copy code"} | ||||||
|           </button> |           </button> | ||||||
|           <button |           <button | ||||||
|             className="text-white bg-none py-0.5 px-2 rounded focus:outline-none hover:bg-blue-700 text-xs" |             className="text-white bg-none py-0.5 pl-2 rounded focus:outline-none text-xs flex items-center" | ||||||
|             onClick={downloadAsFile} |             onClick={downloadAsFile} | ||||||
|           > |           > | ||||||
|             <IconDownload size={16} /> |             <IconDownload size={18} /> | ||||||
|           </button> |           </button> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|  | @ -70,6 +71,7 @@ export const CodeBlock: FC<Props> = ({ language, value, lightMode }) => { | ||||||
|       <SyntaxHighlighter |       <SyntaxHighlighter | ||||||
|         language={language} |         language={language} | ||||||
|         style={lightMode === "light" ? oneLight : oneDark} |         style={lightMode === "light" ? oneLight : oneDark} | ||||||
|  |         customStyle={{margin: 0}} | ||||||
|       > |       > | ||||||
|         {value} |         {value} | ||||||
|       </SyntaxHighlighter> |       </SyntaxHighlighter> | ||||||
|  |  | ||||||
|  | @ -31,3 +31,7 @@ | ||||||
| html { | html { | ||||||
|   background: #202123; |   background: #202123; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | pre:has(div.codeblock) { | ||||||
|  |   padding: 0; | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue