github.com/Jeffail/benthos/v3@v3.65.0/website/src/theme/CodeBlock/index.js (about) 1 /** 2 * Copyright (c) Facebook, Inc. and its affiliates. 3 * 4 * This source code is licensed under the MIT license found in the 5 * LICENSE file in the root directory of this source tree. 6 */ 7 8 import React, {useEffect, useState, useRef} from 'react'; 9 import clsx from 'clsx'; 10 import Highlight, {defaultProps} from 'prism-react-renderer'; 11 import copy from 'copy-text-to-clipboard'; 12 import {usePrismTheme} from '@docusaurus/theme-common'; 13 import Translate, {translate} from '@docusaurus/Translate'; 14 15 import styles from './styles.module.css'; 16 17 import {useThemeConfig} from '@docusaurus/theme-common'; 18 19 export default function CodeBlock({ 20 children, 21 className: languageClassName, 22 }) { 23 const {prism} = useThemeConfig(); 24 25 const [showCopied, setShowCopied] = useState(false); 26 const [mounted, setMounted] = useState(false); 27 // The Prism theme on SSR is always the default theme but the site theme 28 // can be in a different mode. React hydration doesn't update DOM styles 29 // that come from SSR. Hence force a re-render after mounting to apply the 30 // current relevant styles. There will be a flash seen of the original 31 // styles seen using this current approach but that's probably ok. Fixing 32 // the flash will require changing the theming approach and is not worth it 33 // at this point. 34 useEffect(() => { 35 setMounted(true); 36 }, []); 37 38 const button = useRef(null); 39 40 const prismTheme = usePrismTheme(); 41 42 // In case interleaved Markdown (e.g. when using CodeBlock as standalone component). 43 const content = Array.isArray(children) ? children.join('') : children; 44 45 let language = languageClassName && (languageClassName.replace(/language-/, '')); 46 if (!language && prism.defaultLanguage) { 47 language = prism.defaultLanguage; 48 } 49 50 // only declaration OR directive highlight can be used for a block 51 let code = content.replace(/\n$/, ''); 52 53 const handleCopyCode = () => { 54 copy(code); 55 setShowCopied(true); 56 57 setTimeout(() => setShowCopied(false), 2000); 58 }; 59 60 return ( 61 <Highlight {...defaultProps} key={mounted} theme={prismTheme} code={code} language={language}> 62 {({ className, style, tokens, getLineProps, getTokenProps }) => ( 63 <div className={styles.codeBlockContainer}> 64 <div className={clsx(styles.codeBlockContent, language)}> 65 <pre className={`${className}`} style={style}> 66 {tokens.map((line, i) => ( 67 <div {...getLineProps({ line, key: i })}> 68 {line.map((token, key) => ( 69 <span {...getTokenProps({ token, key })} /> 70 ))} 71 </div> 72 ))} 73 </pre> 74 75 <button 76 ref={button} 77 type="button" 78 aria-label={translate({ 79 id: 'theme.CodeBlock.copyButtonAriaLabel', 80 message: 'Copy code to clipboard', 81 description: 'The ARIA label for copy code blocks button', 82 })} 83 className={clsx(styles.copyButton, 'clean-btn')} 84 onClick={handleCopyCode}> 85 {showCopied ? ( 86 <Translate 87 id="theme.CodeBlock.copied" 88 description="The copied button label on code blocks"> 89 Copied 90 </Translate> 91 ) : ( 92 <Translate 93 id="theme.CodeBlock.copy" 94 description="The copy button label on code blocks"> 95 Copy 96 </Translate> 97 )} 98 </button> 99 </div> 100 </div> 101 )} 102 </Highlight> 103 ); 104 }