github.com/Jeffail/benthos/v3@v3.65.0/website/src/theme/CodeSnippet/index.js (about) 1 import React, {useEffect, useState, useRef} from 'react'; 2 import clsx from 'clsx'; 3 import Highlight, {defaultProps} from 'prism-react-renderer'; 4 import copy from 'copy-text-to-clipboard'; 5 import {useColorMode} from '@docusaurus/theme-common'; 6 import Translate, {translate} from '@docusaurus/Translate'; 7 import Link from '@docusaurus/Link'; 8 9 import monokai from "@site/src/plugins/prism_themes/monokai"; 10 import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; 11 12 import styles from './styles.module.css'; 13 14 function CodeSnippet(props) { 15 const { 16 siteConfig: { 17 themeConfig: {prism = {}}, 18 }, 19 } = useDocusaurusContext(); 20 21 const [showCopied, setShowCopied] = useState(false); 22 const [mounted, setMounted] = useState(false); 23 // The Prism theme on SSR is always the default theme but the site theme 24 // can be in a different mode. React hydration doesn't update DOM styles 25 // that come from SSR. Hence force a re-render after mounting to apply the 26 // current relevant styles. There will be a flash seen of the original 27 // styles seen using this current approach but that's probably ok. Fixing 28 // the flash will require changing the theming approach and is not worth it 29 // at this point. 30 useEffect(() => { 31 setMounted(true); 32 }, []); 33 34 const {isDarkTheme} = useColorMode(); 35 const lightModeTheme = prism.theme || monokai; 36 const darkModeTheme = prism.darkTheme || lightModeTheme; 37 const prismTheme = isDarkTheme ? darkModeTheme : lightModeTheme; 38 39 const button = useRef(null); 40 41 const { 42 lang = 'yaml', 43 config, 44 copyBit, 45 further, 46 } = props; 47 48 let copySnippet = copyBit || config; 49 const handleCopyCode = () => { 50 copy(copySnippet); 51 setShowCopied(true); 52 53 setTimeout(() => setShowCopied(false), 2000); 54 }; 55 56 return ( 57 <Highlight {...defaultProps} key={mounted} theme={prismTheme} code={config} language={lang}> 58 {({ className, style, tokens, getLineProps, getTokenProps }) => ( 59 <div className={styles.codeBlockContainer}> 60 <div className={clsx(styles.codeBlockContent, lang)}> 61 <pre className={`${className}`} style={style}> 62 {tokens.map((line, i) => ( 63 <div {...getLineProps({ line, key: i })}> 64 {line.map((token, key) => ( 65 <span {...getTokenProps({ token, key })} /> 66 ))} 67 </div> 68 ))} 69 </pre> 70 71 <button 72 ref={button} 73 type="button" 74 aria-label={translate({ 75 id: 'theme.CodeBlock.copyButtonAriaLabel', 76 message: 'Copy code to clipboard', 77 description: 'The ARIA label for copy code blocks button', 78 })} 79 className={clsx(styles.copyButton, 'clean-btn')} 80 onClick={handleCopyCode}> 81 {showCopied ? ( 82 <Translate 83 id="theme.CodeBlock.copied" 84 description="The copied button label on code blocks"> 85 Copied 86 </Translate> 87 ) : ( 88 <Translate 89 id="theme.CodeBlock.copy" 90 description="The copy button label on code blocks"> 91 Copy 92 </Translate> 93 )} 94 </button> 95 96 {further && <Link 97 className={clsx(styles.furtherButton, 'button button--outline button--primary')} 98 to={further}> 99 Read about 100 </Link>} 101 </div> 102 </div> 103 )} 104 </Highlight> 105 ); 106 } 107 108 export default CodeSnippet;